/**
 * PHRASE.cc
 *
 * part of emoSyn
 *
 * Copyright (C) 2000  Felix Burkhardt
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2 of the License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * author's contact: felixbur@gmx.de 
*/

#include "phrase.h"

uint phrase::MeanF0() {
  calcMeanF0();
  return meanF0;
}

void phrase::calcMeanF0() {
  uint f0Sum=0, f0Num=0;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    syllableVec[syl].calcMeanF0();
    for (uint pho=0; pho<syllableVec[syl].PhonVec().size(); pho++) { 
      if (syllableVec[syl].PhonVec()[pho].Voiced()) {
	for (uint f0v=0; f0v<syllableVec[syl].PhonVec()[pho].F0Vec().size(); f0v++) {
	  f0Sum += syllableVec[syl].PhonVec()[pho].F0Vec()[f0v];
	}
	f0Num +=  syllableVec[syl].PhonVec()[pho].FrameNum();
      }
    }
  }
  
  meanF0 = f0Num>0 ? (uint) f0Sum/f0Num : 0;
}

double phrase::F0Range() {
  uint minf0=A_HIGH_INT, maxf0=0;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonVec().size(); pho++) { 
      if (syllableVec[syl].PhonVec()[pho].Voiced()) {
	for (uint f0v=0; f0v<syllableVec[syl].PhonVec()[pho].F0Vec().size(); f0v++) {
	  if (minf0 > syllableVec[syl].PhonVec()[pho].F0Vec()[f0v] &&
	      syllableVec[syl].PhonVec()[pho].F0Vec()[f0v]>0)
	    minf0 = syllableVec[syl].PhonVec()[pho].F0Vec()[f0v];
	  if (maxf0 < syllableVec[syl].PhonVec()[pho].F0Vec()[f0v])
	    maxf0 = syllableVec[syl].PhonVec()[pho].F0Vec()[f0v];	  
	}
      }
    }
  }
  return Hz2ST(minf0, maxf0); 
}



void phrase::calcDur() {
  uint durSum=0;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonVec().size(); pho++) { 
      durSum +=  syllableVec[syl].PhonVec()[pho].Dur();
    }
  }
  dur = durSum;
}

void phrase::printSyllableVec(std::ostream &outFile) {
  for (uint i=0; i<syllableVec.size(); i++) {
    syllableVec[i].printPhonVec(outFile);
    if (syllableVec[i].PhonNum()<4)
      outFile << "\t";
    outFile << "\taccentType = " << (uint) syllableVec[i].Accent()<<",";
    outFile << "\t";
    outFile << "avr. f0 = " << syllableVec[i].MeanF0() << "\n";
  }
}

void phrase::printPhonFeatures(std::ostream &outFile) {
  phon *pP;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      pP = &syllableVec[syl].PhonVec()[pho];
      outFile <<  (*pP).Name() << " " << (*pP).Diphtong() << "\n"; 
	//tmpPhonFeatures.voiced << "\n";     
    } 
  }
}


void phrase::printPhonMeanF0(std::ostream &outFile) {
  std::vector<phon> tmpPhonVec;  
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    tmpPhonVec = syllableVec[syl].PhonVec();
    for (uint pho=0; pho<tmpPhonVec.size(); pho++) {      
      outFile << tmpPhonVec[pho].MeanF0() << " ";
    }
    outFile << "\t"; 
  }
  outFile << "\n"; 
}

void phrase::makeTest(globalsT globals, uint dur) {
  syllable tmpSyl;
  phon tmpPhon("_", dur, globals);
  tmpSyl.addPhon(tmpPhon);
  syllableVec.push_back(tmpSyl);
  calcDur();
}

void phrase::printKlattFile(std::ostream &outFile) {
  outFile <<  "# parameter file for the klatt-formant speech-synthesizer, implementation of iles & simmons, (version with comments possible!) \n";
  outFile <<  "# generated by emoSyn - speechsynthesizer-frontend for emotional speech, author felixbur@kgw.tu-berlin.de\n";
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      outFile <<  "# name of phone: " << syllableVec[syl].PhonVec()[pho].Name() << "\n";
      outFile <<  "# meaning of parameters: \n";
      outFile <<  "# f0 av f1 b1 f2 b2 f3 b3 f4 b4 f5 b5 f6 b6 fnz bnz fnp bnp asp kopen aturb tilt af skew a1 b1p a2 b2p a3 b3p a4 b4p a5 b5p a6 b6p anp ab avp gain\n# values:\n";
      syllableVec[syl].PhonVec()[pho].printKlattFrames(outFile);
    }
  }
}

void phrase::modelKlattParameters(globalsT &globals) {
  phon *tmpPhonP;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      tmpPhonP =  &(syllableVec[syl].PhonVec()[pho]);
      (*tmpPhonP).setSoundSource(globals);
      (*tmpPhonP).setArticulationTractFilter(globals);
    }
  }
}

void phrase::modelFeatures(globalsT &globals) {
  phon *pP, *nextpP, *prevpP=NULL;

  for (uint syl=0; syl<syllableVec.size(); syl++) {
    uint sylMeanF0 = syllableVec[syl].MeanF0();
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      if (pho==syllableVec[syl].PhonNum()-1)
	if (syl==syllableVec.size()-1) 
	  nextpP = NULL;
	else
	  nextpP = &(syllableVec[syl+1].PhonVec()[0]);
      else
	nextpP = &(syllableVec[syl].PhonVec()[pho+1]);

      pP =  &(syllableVec[syl].PhonVec()[pho]);
      (*pP).modelFeatures(sylMeanF0, globals, prevpP, nextpP);
      prevpP = pP;
    }
  }
}

void phrase::printPhoFile(std::ostream &outFile, globalsT glob) {
  std::vector<uint> tmpF0ValVec(0);
  std::vector<uint> tmpF0TimeVec(0);
  phon *pP;
  uint time;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      pP = &syllableVec[syl].PhonVec()[pho];
      if (glob.copyDB) {
	outFile << (*pP).Name() << " ";
	outFile << (*pP).Dur() << " ";
	if ((*pP).Voiced()) {
	  for (uint f0Val=0; f0Val<(*pP).F0Vec().size();f0Val++) {
	    time = f0Val*(100/(*pP).F0Vec().size());
	    outFile << time << " " << (*pP).F0Vec()[f0Val]/10 << " ";
	  }
	}
      } else { 
	tmpF0ValVec =  (*pP).F0ValVec();
	tmpF0TimeVec = (*pP).F0TimeVec();
	outFile << (*pP).Name() << " ";
	outFile << (*pP).Dur() << " ";
	for (uint f0Val=0; f0Val<(*pP).FrameNum();f0Val++)
	  outFile << tmpF0TimeVec[f0Val] << " "
		  << tmpF0ValVec[f0Val]*10 << " ";
      }
      outFile << "\n"; 
    }
    if (glob.copyDB)
      outFile << "- " << (int) syllableVec[syl].Accent() << "\n"; 
  }
  outFile << "\n"; 
}

void phrase::printLabelFile(std::ostream &outFile, globalsT globals) {
  double time=0;  
  phon *pP;

  outFile << "signal emoSyn-output\n";
  outFile << "type 0\n";
  outFile << "comment created by emoSyn\n";
  outFile << "font -misc-*-bold-*-*-*-15-*-*-*-*-*-*-*\n";
  outFile << "separator ;\n";
  outFile << "nfields 1\n";
  outFile << "#\n";
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      pP = &syllableVec[syl].PhonVec()[pho];
      outFile << "\t" << time << "\t-1 ";
      outFile << (*pP).Name();
      outFile << "\n"; 
      // print features: overshoot, undershoot
      if ((*pP).PhonFeatures().overshoot) {
	outFile << "\t" << time << "\t-1 " << "+overshoot\n";  
      } 
      if ((*pP).PhonFeatures().undershoot) {
	outFile << "\t" << time << "\t-1 " << "+undershoot\n";  
      } 
      // print features: breathy
      if ((*pP).PhonFeatures().breathy) {
	double bS = (*pP).PhonFeatures().brtStart*(double) globals.ui / 1000;
	outFile << "\t" << time + bS << "\t-1 " << "+brt\n";
	if ((*pP).PhonFeatures().brtStop < (*pP).Dur()) {
	  double bE = (*pP).PhonFeatures().brtStop*(double) globals.ui / 1000;
	  outFile << "\t" << time + bE << "\t-1 " << "-brt\n";  
	}
      }
      // print features: voiced      
      if ((*pP).PhonFeatures().voiced) {
	if (!(*pP).Voiced()) {
	  double vS = (*pP).PhonFeatures().vocStart*(double) globals.ui / 1000;	  
	  outFile << "\t" << time + vS << "\t-1 " << "+voc\n";
	  if ((*pP).PhonFeatures().vocStop < (*pP).Dur()) {
	    double vE = (*pP).PhonFeatures().vocStop*(double) globals.ui / 1000;
	    outFile << "\t" << time + vE << "\t-1 " << "-voc\n";  
	  }
	} else {
	  double vE = (*pP).PhonFeatures().vocStop*(double) globals.ui / 1000;	  
	  outFile << "\t" << time + vE << "\t-1 " << "-voc\n";
	  if ((*pP).PhonFeatures().vocStart < (*pP).Dur()) {
	    double vS = (*pP).PhonFeatures().vocStart*(double) globals.ui / 1000;	  
	    outFile << "\t" << time + vS << "\t-1 " << "+voc\n";  
	  }
	}
      }
      // print features: laryngealized
      if ((*pP).PhonFeatures().creaky) {
	double bS = (*pP).PhonFeatures().creakyStart*(double) globals.ui / 1000;
	outFile << "\t" << time + bS << "\t-1 " << "+lar\n";
	if ((*pP).PhonFeatures().creakyStop < (*pP).Dur()) {
	  double bE = (*pP).PhonFeatures().creakyStop*(double) globals.ui / 1000;
	  outFile << "\t" << time + bE << "\t-1 " << "-lar\n";  
	}
      }
      time += (double) (*pP).Dur()/1000;
    }
  }
  outFile << "\n"; 
}

void phrase::readPhoFile(std::istream &inFile, globalsT &glob) {
  std::string buffer;
  //  phon tmpPhon;
  std::string name;
  const std::string syllableSeperator = "-";
  int dur;
  syllable tmpSyl;
  std::vector<uint> tmpF0ValVec(0);
  std::vector<uint> tmpF0TimeVec(0);
  PHON_FEATURES tmpPhonFeatures;

  initPhonFeatures(tmpPhonFeatures);

  while (getline(inFile, buffer)) {

    // a valid line in a pho-file is either a comment
    if (buffer != "" && buffer.at(0) != '#') {
      std::vector<std::string> tokenVec;
      tokenVec = string2vec(buffer);
      
      
      // or a syllable-separator
     if (tokenVec[0] == syllableSeperator) { // this is a syllable border
       // read the accent-type
       if (tokenVec.size()>1) {
         tmpSyl.setAccent((ACCENT_TYPE) atoi(tokenVec[1].c_str()));
       } else {
         error("phrase::readPhoFile: missing accentType in phon-feature near phon "+name+"\n", -3);
       }
        // push the last phonFeatures
	phon *tmpPhonP;
	tmpPhonP = &tmpSyl.PhonVec()[tmpSyl.PhonNum()-1];
	(*tmpPhonP).setPhonFeatures(tmpPhonFeatures);
	initPhonFeatures(tmpPhonFeatures);
	tmpSyl.calcMeanF0();
	// push the syllable
	syllableVec.push_back(tmpSyl);
	// clear the tmp-syllable
	tmpSyl.clearPhonVec();
	
	// or a feature-flag
     } else if (tokenVec[0] == "+voc") {
	if (tokenVec.size()>1) {
	  tmpPhonFeatures.vocStart = msec2frames(atoi(tokenVec[1].c_str()), glob);
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);	
	if (!tmpPhonFeatures.voiced)
	  tmpPhonFeatures.vocStop = A_HIGH_INT;
	tmpPhonFeatures.voiced = true;
      } else if (tokenVec[0] == "-voc") {
	if (!tmpPhonFeatures.voiced)
	  tmpPhonFeatures.vocStart = 0;
	if (tokenVec.size()>1) {
	  tmpPhonFeatures.vocStop = msec2frames(atoi(tokenVec[1].c_str()), glob);
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);
	tmpPhonFeatures.voiced = true;
      } else if (tokenVec[0] == "+brt") {
	if (tokenVec.size()>2) {
	  tmpPhonFeatures.brtStart = msec2frames(atoi(tokenVec[1].c_str()), glob);
	  tmpPhonFeatures.brtRate = atoi(tokenVec[2].c_str());	  
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);
	tmpPhonFeatures.brtStop = A_HIGH_INT;
	tmpPhonFeatures.breathy = true;
      } else if (tokenVec[0] == "-brt") {
	if (!tmpPhonFeatures.breathy)
	  tmpPhonFeatures.brtStart = 0;
	if (tokenVec.size()>1) {
	  tmpPhonFeatures.brtStop = msec2frames(atoi(tokenVec[1].c_str()), glob);
	  if (!tmpPhonFeatures.breathy) { // if it's not allready breathy, get rate
	    if (tokenVec.size()>2)     
	      tmpPhonFeatures.brtRate = atoi(tokenVec[2].c_str());	
	    else 
	      error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);
	  }
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);
	tmpPhonFeatures.breathy = true;
      } else if (tokenVec[0] == "+nas") {
	if (tokenVec.size()>1) {
	tmpPhonFeatures.nasStart = msec2frames(atoi(tokenVec[1].c_str()), glob);
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);
	tmpPhonFeatures.nasStop = A_HIGH_INT;
	tmpPhonFeatures.nasalized = true;
      } else if (tokenVec[0] == "-nas") {
	if (!tmpPhonFeatures.nasalized)
	  tmpPhonFeatures.nasStart = 0;
	if (tokenVec.size()>1) {
	  tmpPhonFeatures.nasStop = msec2frames(atoi(tokenVec[1].c_str()), glob);
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);
	tmpPhonFeatures.nasalized = true;
      } else if (tokenVec[0] == "+lar") {
	if (tokenVec.size()>2) {
	  tmpPhonFeatures.larStart = msec2frames(atoi(tokenVec[1].c_str()), glob);
	  tmpPhonFeatures.larRate = atoi(tokenVec[2].c_str());
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);
	tmpPhonFeatures.larStop = A_HIGH_INT;
	tmpPhonFeatures.laryngealized = true;
      } else if (tokenVec[0] == "-lar") {
	if (!tmpPhonFeatures.laryngealized)
	  tmpPhonFeatures.larStart = 0;
	if (tokenVec.size()>1) {
	  tmpPhonFeatures.larStop = msec2frames(atoi(tokenVec[1].c_str()), glob);
	  if (!tmpPhonFeatures.laryngealized) {
	    if (tokenVec.size()>2) 
	      tmpPhonFeatures.larRate = atoi(tokenVec[2].c_str());
	    else 
	      error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);  
	  }  
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);
	tmpPhonFeatures.laryngealized = true;

      } else if (tokenVec[0] == "+spr") {
	if (tokenVec.size()>1) {
	  tmpPhonFeatures.spreadRate = atoi(tokenVec[1].c_str());
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);
	tmpPhonFeatures.spread = true;
      } else if (tokenVec[0] == "+rounded") {
	if (tokenVec.size()>1) {
	  tmpPhonFeatures.roundedRate = atoi(tokenVec[1].c_str());
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);
	tmpPhonFeatures.rounded = true;	
      } else if (tokenVec[0] == "+tense") {
	tmpPhonFeatures.tense = true;
	if (tokenVec.size()>1) {
	  tmpPhonFeatures.tenseRate = atoi(tokenVec[1].c_str());
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);
	
      } else if (tokenVec[0] == "+falsett") {
	tmpPhonFeatures.falsett = true;
	if (tokenVec.size()>1) {
	  tmpPhonFeatures.falsettRate = atoi(tokenVec[1].c_str());
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);
	
      } else if (tokenVec[0] == "+whisper") {
	tmpPhonFeatures.whisper = true;
	if (tokenVec.size()>1) {
	  tmpPhonFeatures.whisperRate = atoi(tokenVec[1].c_str());
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);

      } else if (tokenVec[0] == "+lax") {
	tmpPhonFeatures.lax = true;
      } else if (tokenVec[0] == "-undershoot") {
	tmpPhonFeatures.undershoot = true;
	if (tokenVec.size()>1) {
	  tmpPhonFeatures.undershootRate = atoi(tokenVec[1].c_str());
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);

      } else if (tokenVec[0] == "+overshoot") {
	tmpPhonFeatures.overshoot = true;
	if (tokenVec.size()>1) {
	  tmpPhonFeatures.overshootRate = atoi(tokenVec[1].c_str());
	} else 
	  error("phrase::readPhoFile: missing parameter in phon-feature near phon "+name+"\n", -3);

	// or a valid pho-file line is a phone-description
      } else {
	name = tokenVec[0];
	if (tokenVec.size() > 1) {	
	  dur = atoi(tokenVec[1].c_str());
	} else {
	  error("phrase::readPhoFile: no duration at phon "+name+" \n",-1);
	}
	if ((tokenVec.size()-2)%2 == 0) {
	  for (uint i=2; i<tokenVec.size(); i=i+2) {
	    tmpF0TimeVec.push_back(atoi(tokenVec[i].c_str()));
	    // we get f0Vals in 10ths of herz
	    tmpF0ValVec.push_back(atoi(tokenVec[i+1].c_str())*10);	    
	  }
	} else {
	  error("phrase::readPhoFile: error in intonation description at phon "+name+" \n",-1);
	}
	phon tmpPhon(name, dur, glob);
	tmpPhon.setF0ValVec(tmpF0ValVec);
	tmpPhon.setF0TimeVec(tmpF0TimeVec);
	tmpPhon.modelIntonation(glob);
	
	tmpF0ValVec.erase(tmpF0ValVec.begin(), tmpF0ValVec.end());
	tmpF0TimeVec.erase(tmpF0TimeVec.begin(), tmpF0TimeVec.end());
	
	tmpSyl.addPhon(tmpPhon);
	if (tmpSyl.PhonNum()>1) {
	  phon *tmpPhonP;
	  tmpPhonP = &tmpSyl.PhonVec()[tmpSyl.PhonNum()-2];
	  (*tmpPhonP).setPhonFeatures(tmpPhonFeatures);
	} else
	  tmpPhon.setPhonFeatures(tmpPhonFeatures);
	
	initPhonFeatures(tmpPhonFeatures);
      }
    } // if no comment or empty line
  } // while (getline(inFile, buffer))
  calcDur();
} // readPhoFile(istream &inFile)

void phrase::readPhoList(std::istream &inFile, globalsT &glob) {
  std::string buffer;
  //  phon tmpPhon;
  std::string name;
  const std::string syllableSeperator = "-";
  syllable tmpSyl;
  
  while (getline(inFile, buffer)) {
    
    // a valid line in a pho-file is either a comment
    if (buffer != "" && buffer.at(0) != '#') {
      std::vector<std::string> tokenVec;
      tokenVec = string2vec(buffer);
      
      
      // or a syllable-separator
      if (tokenVec[0] == syllableSeperator) { // this is a syllable border
	// read the accent-type
	if (tokenVec.size()>1) {
	  tmpSyl.setAccent((ACCENT_TYPE) atoi(tokenVec[1].c_str()));
	} else {
	  error("phrase::readPhoFile: missing accentType in phon-feature near phon "+name+"\n", -3);
	}
	// push the syllable
	syllableVec.push_back(tmpSyl);
	// clear the tmp-syllable
	tmpSyl.clearPhonVec();
	
	// or a valid pho-file line is a phone-description
      } else {
	name = tokenVec[0];
	phon tmpPhon(name, 0, glob);
      
	tmpSyl.addPhon(tmpPhon);
      }
      
    } // if no comment or empty line
  } // while (getline(inFile, buffer))
} // readPhoList(istream &inFile)

// duration modifications:
/* *******************************************************************
   changeSpeechRate (uint rate, globalsT globals, int method)
   args: uint rate, globalsT glob, int method
   returns: none
   effect: 
   if method = 0
   change duration of all phones in the utterance by factor <rate>
   if method = 1
   phrasestressed vowels get 100% change,
   wordstressed vowels get 90 % change,
   all others get 80 % change,
   *******************************************************************
*/
void  phrase::changeSpeechRate(uint rate, globalsT glob, int method) {
  int absChange, wordChange, vowelChange, consChange;
  phon *pP;  
  uint newDur;
  if (method == 0) {
    for (uint syl=0; syl<syllableVec.size(); syl++) {
      for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	if (!(syl==0&&pho==0) &&
	    !(syl==syllableVec.size()-1&&pho==syllableVec[syl].PhonNum()-1)) {
	  
	  pP = &syllableVec[syl].PhonVec()[pho];
	  if (!(rate>100 && syllableVec[syl].PhonVec()[pho].Diphtong())) {
	    newDur = (*pP).Dur() * rate/100;     
	    (*pP).changeDur(newDur, glob);
	  }
	}
      }
    }
  } else if (method == 1) {
    absChange = abs(100-(int)rate);
    if (rate>100) {
      wordChange = 100 + (int) (absChange*0.9);
      vowelChange = 100 + (int) (absChange*0.7);
      consChange = 100 + (int) (absChange*0.5);
    } else {
      wordChange = 100 - (int) (absChange*0.9);
      vowelChange = 100 - (int) (absChange*0.7);
      consChange = 100 - (int) (absChange*0.5);
    }
    //    cout << wordChange<<" "<<vowelChange<<" "<<consChange<<"\n";
    for (uint syl=0; syl<syllableVec.size(); syl++) {
      for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	if (!(syl==0&&pho==0) &&
	    !(syl==syllableVec.size()-1&&pho==syllableVec[syl].PhonNum()-1)) {
	  
	  pP = &syllableVec[syl].PhonVec()[pho];
	  if (syllableVec[syl].Accent()==sentence && (*pP).Type()==vowel)
	    newDur = syllableVec[syl].PhonVec()[pho].Dur() * rate/100;
	  else if  (syllableVec[syl].Accent()==word && (*pP).Type()==vowel)
	    newDur = syllableVec[syl].PhonVec()[pho].Dur() * wordChange/100;
	  else if  ((*pP).Type()==vowel)
	    newDur = syllableVec[syl].PhonVec()[pho].Dur() * vowelChange/100;
	  else
	    newDur = syllableVec[syl].PhonVec()[pho].Dur() * consChange/100;
	  
	  syllableVec[syl].PhonVec()[pho].changeDur(newDur, glob);
	}
      }
    }
  } else {
    error("phrase::changeSpeechRate: undefined method", -3);
  }
  calcDur();
  if (glob.verbose)
    std::cerr << "changed speechrate at "<<rate<<" percent\n";
}
/* *******************************************************************
   changeDurStressed (uint rate, uint both, globalsT globals)
   args: uint rate, uint both, globalsT globals
   returns: none
   effect: change duration of stressed syllables by changing duration
   of vowel in syllable (following kienast99 the shortening/lengthening 
   of syllables effects primarily the vowels)
   - the arg <both> decides whether word-accents are counted or not.
   *******************************************************************
   */
void  phrase::changeDurStressed(uint rate, uint both, globalsT glob) {
  phon *pP;
  if (rate < MIN_SPEECHRATE || rate > MAX_SPEECHRATE)
    error ("phrase::changeDurStressed: rate < MIN_SPEECHRATE || rate > MAX_SPEECHRATE", -3);

  if (both) {
    for (uint syl=0; syl<syllableVec.size(); syl++) {
      if (syllableVec[syl].Accent()==word ||syllableVec[syl].Accent()==sentence) {
	for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {	    
	  if (!(syl==0&&pho==0) &&
	      !(syl==syllableVec.size()-1&&pho==syllableVec[syl].PhonNum()-1)) {
	    pP = &syllableVec[syl].PhonVec()[pho];
	    if ((*pP).Type()==vowel) {
	      if (!(rate>100 && (*pP).Diphtong())) {
		uint newDur = (*pP).Dur() * rate/100;     
		(*pP).changeDur(newDur, glob);
	      }
	    }
	  }
	}
      }
    }
  } else { // only sentence-accent
    for (uint syl=0; syl<syllableVec.size(); syl++) {
      if (syllableVec[syl].Accent()==sentence) {
	for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	  if (!(syl==0&&pho==0) &&
	      !(syl==syllableVec.size()-1&&pho==syllableVec[syl].PhonNum()-1)) {
	    
	    pP = &syllableVec[syl].PhonVec()[pho];
	    if ((*pP).Type()==vowel) {
	      uint newDur = (*pP).Dur() * rate/100;     
	      (*pP).changeDur(newDur, glob);
	    }
	  }
	}
      }
    }      
  }
  calcDur();
  if (glob.verbose) {
    if (both)
      std::cerr << "changed duration of all stressed syllables at "<<rate<<" percent\n";
    else
      std::cerr << "changed duration of phrase-stressed syllables at "<<rate<<" percent\n";      
  }
}
  /* *******************************************************************
     changeDurNonStressed (uint rate, uint both, globalsT globals)
     args: uint rate, uint both, globalsT globals
     returns: none
     effect: change duration of nonstressed syllables by changing duration
     of vowel in syllable (following kienast99 the shortening/lengthening of syllables 
     effects primarily the vowels)
     - the arg <both> decides whether word-accents are counted or not.
     *******************************************************************
   */

void  phrase::changeDurNonStressed(uint rate, uint both, globalsT glob) {
  phon *pP;
  if (rate < MIN_SPEECHRATE || rate > MAX_SPEECHRATE)
    error ("phrase::changeDurNonStressed: rate < MIN_SPEECHRATE || rate > MAX_SPEECHRATE", -3);

  if (both) {
    for (uint syl=0; syl<syllableVec.size(); syl++) {
      if (syllableVec[syl].Accent()==word ||syllableVec[syl].Accent()==none) {
	for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {	    
	  if (!(syl==0&&pho==0) &&
	      !(syl==syllableVec.size()-1&&pho==syllableVec[syl].PhonNum()-1)) {
	    pP = &syllableVec[syl].PhonVec()[pho];
	    if ((*pP).Type()==vowel) {
	      uint newDur = (*pP).Dur() * rate/100;     
	      (*pP).changeDur(newDur, glob);
	    }
	  }
	}
      }
    }
  } else { // only non-accent
    for (uint syl=0; syl<syllableVec.size(); syl++) {
      if (syllableVec[syl].Accent()==none) {
	for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {	    
	  if (!(syl==0&&pho==0) &&
	      !(syl==syllableVec.size()-1&&pho==syllableVec[syl].PhonNum()-1)) {
	    pP = &syllableVec[syl].PhonVec()[pho];
	    if ((*pP).Type()==vowel) {
	      uint newDur = (*pP).Dur() * rate/100;     
	      (*pP).changeDur(newDur, glob);
	    }
	  }
	}
      }
    }      
  }
  calcDur();
  if (glob.verbose) {
    if (both)
      std::cerr << "changed duration of non phrase-stressed syllables at "<<rate<<" percent\n";
    else
      std::cerr << "changed duration of non stressed syllables at "<<rate<<" percent\n";      
  }
}
/* *******************************************************************
   changeDurManner (PHON_MANNER manner, uint rate, globalsT globals)
   args: uint rate, globalsT globals
   returns: none
   effect: change duration of specified phone-manners
   *******************************************************************
   */  
void phrase::changeDurManner(PHON_MANNER manner, uint rate, globalsT glob) {
  phon *pP;
  if (rate < MIN_SPEECHRATE || rate > MAX_SPEECHRATE)
    error ("phrase::changeDurManner: rate < MIN_SPEECHRATE || rate > MAX_SPEECHRATE", -3);
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {	    
      if (!(syl==0&&pho==0) &&
	  !(syl==syllableVec.size()-1&&pho==syllableVec[syl].PhonNum()-1)) {
	pP = &syllableVec[syl].PhonVec()[pho];
	if ((*pP).Manner()==manner) {
	  uint newDur = (*pP).Dur() * rate/100;     
	  (*pP).changeDur(newDur, glob);
	}
      }
    }
  }
  calcDur();
  if (glob.verbose)
    std::cerr << "changed duration of phones with specified manner at "<<rate<<" percent\n";
}
  // intensity modifications

/* *******************************************************************
   changeStressedInt (int dBVal, uint both, globalsT glob)
   args: uint rate, uint both, globalsT globals
   returns: none
   effect: change intensity stressed syllables 
   - the arg <both> decides whether word-accents are counted or not.
   *******************************************************************
   */

void phrase::changeStressedInt(int dBVal, uint both, globalsT glob) {
  if (both) {
    for (uint syl=0; syl<syllableVec.size()-1; syl++) {
      if (syllableVec[syl].Accent()==sentence) {
	syllableVec[syl].changeAvrInt(dBVal);
      }
      if (syllableVec[syl].Accent()==word) {
	syllableVec[syl].changeAvrInt(dBVal/2);
      }
      
    }
  } else { // only sentence-accent
    for (uint syl=0; syl<syllableVec.size(); syl++) {
      if (syllableVec[syl].Accent()==sentence) {
	syllableVec[syl].changeAvrInt(dBVal);
      }
    }      
  }
  if (both)
    std::cerr << "changed avr. intensuty of all stressed syllables at "<<dBVal<<" dB\n";
  else
    std::cerr << "changed avr. intensity of phrase-stressed syllables at "<<dBVal<<" dB\n";      
}

// f0-contour modifications:

/* *******************************************************************
   void changeMeanF0(uint rate, globalsT glob)
   args: uint rate
   returns: none
   effect: all nonzero f0Vals get multiplied by <rate> in percent.
   (so rate=100 means no change)
   *******************************************************************
   */
void phrase::changeMeanF0(uint rate, globalsT glob) {
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    syllableVec[syl].changeMeanF0(rate);
  }
  calcMeanF0();
  if (glob.verbose)
    std::cerr << "changed avr. F0 at "<<rate<<" percent\n";
}
/* *******************************************************************
   void smootheF0(uint winsize, globalsT glob)
   args: winsize
   returns: none
   effect: all f0Vals get centerFiltered around winsize
   *******************************************************************
   */
void phrase::smootheF0(uint winsize, globalsT glob) {
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      if (syllableVec[syl].PhonVec()[pho].Voiced() && syllableVec[syl].PhonVec()[pho].Manner() != stop_voiced) {
	syllableVec[syl].PhonVec()[pho].smootheF0(winsize);
      }
    }
  }
  if (glob.verbose)
    std::cerr << "smoothing f0 with winSize: "<<winsize<<"\n";
}
  /* ******************************************************************* 
     changeStressedAvrF0 (uint rate, uint both, globalsT glob)
     args: uint rate, uint both
     returns: none
     effect: change avr pitch of stressed syllables by multiplying
     all nonzero f0Vals by <rate>
     - the arg <both> decides whether word-accents are counted or not.
     last syllable is not allowed for
     *******************************************************************
   */
void phrase::changeStressedAvrF0(uint rate, uint both, globalsT glob) {
  if (both) {
    for (uint syl=0; syl<syllableVec.size()-1; syl++) {
      if (syllableVec[syl].Accent()==word || syllableVec[syl].Accent()==sentence) {
	// cout << syllableVec[syl].MeanF0() << " ";
	syllableVec[syl].changeMeanF0(rate);
	// cout << syllableVec[syl].MeanF0() << "\n";
	
      }
    }
  } else { // only sentence-accent
    for (uint syl=0; syl<syllableVec.size(); syl++) {
      if (syllableVec[syl].Accent()==sentence) {
	syllableVec[syl].changeMeanF0(rate);
      }
    }      
  }
  if (both)
    std::cerr << "changed avr. F0 of all stressed syllables at "<<rate<<" percent\n";
  else
    std::cerr << "changed avr. F0 of phrase-stressed syllables at "<<rate<<" percent\n";      
  calcMeanF0();
}

  /* ******************************************************************* 
     changePreStressedAvrF0 (uint rate, uint both, globalsT glob)
     args: uint rate, uint both
     returns: none
     effect: change avr pitch  of syl before stressed syllables by multiplying
     all nonzero f0Vals by <rate>
     - the arg <both> decides whether word-accents are counted or not.
     last syllable is not allowed for
     *******************************************************************
   */
void phrase::changePreStressedAvrF0(uint rate, uint both, globalsT glob) {
  if (both) {
    for (uint syl=0; syl<syllableVec.size()-1; syl++) {
      if (syllableVec[syl+1].Accent()==word ||syllableVec[syl+1].Accent()==sentence) {
	syllableVec[syl].changeMeanF0(rate);
      }
    }
  } else { // only sentence-accent
    for (uint syl=0; syl<syllableVec.size(); syl++) {
      if (syllableVec[syl+1].Accent()==sentence) {
	syllableVec[syl].changeMeanF0(rate);
      }
    }      
  }
  if (both)
    std::cerr << "changed avr. F0 of all syls prior to stress at "<<rate<<" percent\n";
  else
    std::cerr << "changed avr. F0 of syls prior to phrase-stress at "<<rate<<" percent\n";      
  calcMeanF0();
}

/* *******************************************************************
   void changeF0Range(uint rate, globalsT glob)
   args: uint rate
   returns: none
   effect: all nonzero f0Vals get 
   *******************************************************************
   */
void phrase::changeF0Range(uint rate, globalsT glob) {
  uint lastMean = syllableVec[syllableVec.size()-1].MeanF0();
  for (uint syl=0; syl<syllableVec.size(); syl++)
    syllableVec[syl].changeF0Range(rate, lastMean);
  
  if (glob.verbose)
    std::cerr << "changed F0-range at "<<rate<<" percent\n";
  calcMeanF0();
}

/* *******************************************************************
   void changeVariablility(uint rate, globalsT glob)
   args: uint rate
   returns: none
   effect:
   *******************************************************************
   */
void phrase::changeVariability(uint rate, globalsT glob) {
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    syllableVec[syl].changeF0Range(rate, syllableVec[syl].MeanF0());
  }
  if (glob.verbose)
    std::cerr << "changed F0-variability at "<<rate<<" percent\n";  
  calcMeanF0();
}

/* *******************************************************************
   void changeLastSylContour(CONTOUR_TYPE contour, uint gradient, globalsT glob)
   args: uint rate
   returns: none
   effect: changes pitch-contour of last syllable to <contour>,
   <contour> can be straight, rise or fall
   - straight: 
   - rise/fall: last syllable gets pitch-changed according to <gradient (ST/sec)>, 
   *******************************************************************
   */
void phrase::changeLastSylContour(CONTOUR_TYPE contour, uint gradient, globalsT glob) {
  phon *pP;
  uint start=0, end;
  bool found=false;
  uint lastSyl=syllableVec.size()-1;
  switch (contour) {
  case straight:
    start=syllableVec[lastSyl].MeanF0();
    for (uint pho=0; pho<syllableVec[lastSyl].PhonNum(); pho++) {
      pP = &syllableVec[lastSyl].PhonVec()[pho];
      if ((*pP).Voiced()) {
	(*pP).interpolateF0Vec(start, start);
      }
    }  
    break;
  case rise:
    found=false;
    for (uint pho=0; pho<syllableVec[lastSyl].PhonNum(); pho++) {
      pP = &syllableVec[lastSyl].PhonVec()[pho];
      for (uint i=0; i<(*pP).F0Vec().size(); i++) {
	if ((*pP).F0Vec()[i] != 0) {
	  start = (*pP).F0Vec()[i];
	  found=true;
	  break;
	}
      }
      if (found)
	break;
    }
    for (uint pho=0; pho<syllableVec[lastSyl].PhonNum(); pho++) {
      pP = &syllableVec[lastSyl].PhonVec()[pho];
      if ((*pP).Voiced()) {
	end = (uint) gradient2Hz(start, (*pP).Dur(), gradient);
	// cout <<"start: "<< start << " " << end << "\n";
	(*pP).interpolateF0Vec(start, end);
	start = end;
      }
    }
    break;
  case fall:
    for (uint pho=0; pho<syllableVec[lastSyl].PhonNum(); pho++) {
      pP = &syllableVec[lastSyl].PhonVec()[pho];
      if ((*pP).MeanF0()!=0) {
	start=(*pP).MeanF0();
	break;
      }
    }
    for (uint pho=0; pho<syllableVec[lastSyl].PhonNum(); pho++) {
      pP = &syllableVec[lastSyl].PhonVec()[pho];
      if ((*pP).Voiced()) {
	end = start - ((uint) gradient2Hz(start, (*pP).Dur(), gradient) - start);
	// cout <<"start: "<< start << " " << end << "\n";
	(*pP).interpolateF0Vec(start, end);
	start = end;
      }
    }
    break;
  }
  syllableVec[lastSyl].calcMeanF0();
  calcMeanF0();
  if (glob.verbose)
    std::cerr << "changed f0-countour of last syllable to gradient "<<gradient<<" \n"; 
}
/******************************************************************
  phrase::changePitchContourStressed
  - falling contours start from mean f0Val
  *****************************************************************
 */
void phrase::changePitchContourStressed(CONTOUR_TYPE contour, uint gradient, uint both, globalsT glob) {
  phon *pP;
  uint start=0, end;
  bool found=false;
  if (both) {
    for (uint syl=0; syl<syllableVec.size()-1; syl++) {      
      found=false;
      start=0;
      if (syllableVec[syl].Accent()==word || syllableVec[syl].Accent()==sentence) {
	// cout << syllableVec[syl].MeanF0() << "\n";

	switch (contour) {
	case straight:
	  syllableVec[syl].changeF0Range(gradient);
	  break;
	case rise:
	  found=false;
	  for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	    pP = &syllableVec[syl].PhonVec()[pho];
	    for (uint i=0; i<(*pP).F0Vec().size(); i++) {
	      if ((*pP).F0Vec()[i] != 0) {
		start = (*pP).F0Vec()[i];
		found=true;
		break;
	      }
	    }
	    if (found)
	      break;
	  }
	  for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	    pP = &syllableVec[syl].PhonVec()[pho];
	    if ((*pP).Voiced()) {
	      end = (uint) gradient2Hz(start, (*pP).Dur(), gradient);
	      // cout <<"start: "<< start << " " << end << "\n";
	      (*pP).interpolateF0Vec(start, end);
	      start = end;
	    }
	  }
	  break;
	case fall:
	  start = syllableVec[syl].MeanF0();
	  // start fall from mean f0Val
	  /*
	  for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	    pP = &syllableVec[syl].PhonVec()[pho];
	    if ((*pP).MeanF0()!=0) {
	      start=(*pP).MeanF0();
	      break;
	    }
	  }
	  */
	  // start fall from first nonzero f0Val
	  //	  for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	  //  pP = &syllableVec[syl].PhonVec()[pho];
	  // for (uint i=0; i<(*pP).FrameNum(); i++) {
	  //  if ((*pP).F0Vec()[i]!=0) {
	  //start=(*pP).F0Vec()[i];
	  //break;
	  //  }
	  //}
	  //}
	  for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	    pP = &syllableVec[syl].PhonVec()[pho];
	    if ((*pP).Voiced()) {
	      end = start - ((uint) gradient2Hz(start, (*pP).Dur(), gradient) - start);
	      // cout <<"start: "<< start << " " << end << "\n";
	      (*pP).interpolateF0Vec(start, end);
	      start = end;
	    }
	  }
	  break;
	}
      }
    } 
  } else { // only sentence-accent
    for (uint syl=0; syl<syllableVec.size()-1; syl++) {
      if (syllableVec[syl].Accent()==sentence) {
	switch (contour) {
	case straight:
	  syllableVec[syl].changeF0Range(gradient);
	  break;
	case rise:
	  found=false;
	  for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	    pP = &syllableVec[syl].PhonVec()[pho];
	    for (uint i=0; i<(*pP).F0Vec().size(); i++) {
	      if ((*pP).F0Vec()[i] != 0) {
		start = (*pP).F0Vec()[i];
		found=true;
		break;
	      }
	    }
	    if (found)
	      break;
	  }
	  for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	    pP = &syllableVec[syl].PhonVec()[pho];
	    if ((*pP).Voiced()) {
	      end = (uint) gradient2Hz(start, (*pP).Dur(), gradient);
	      (*pP).interpolateF0Vec(start, end);
	      start = end;
	    }
	  }
	  break;
	case fall:
	  // find first nonzero f0Val
	  for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	    pP = &syllableVec[syl].PhonVec()[pho];
	    for (uint i=0; i<(*pP).FrameNum(); i++) {
	      if ((*pP).F0Vec()[i]!=0) {
		start=(*pP).F0Vec()[i];
		break;
	      }
	    }
	  }
	  for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	    pP = &syllableVec[syl].PhonVec()[pho];
	    if ((*pP).Voiced()) {
	      end = start - ((uint) gradient2Hz(start, (*pP).Dur(), gradient) - start);
	      (*pP).interpolateF0Vec(start, end);
	      start = end;
	    }
	  }
	  break;
	}
      }
    }
  } 
  if (glob.verbose)
    std::cerr << "changed f0-countour of stressed syllables to gradient "<<gradient<<" \n"; 
  calcMeanF0();
}

/* *******************************************************************
   void changePhraseContour(CONTOUR_TYPE contour, uint rate, globalsT glob)
   args: uint rate
   returns: none
   effect: changes pitch-contour of whole phrase to <contour>,
   <contour> can be straight, rise or fall
   - straight: all syllable-meanF0Vals become meanF0Val
   - rise/fall: last syllable gets pitch-changed according to <rate>, 
   all syllables before get changed in percentage to distance from 
   last syllable 
   *******************************************************************
   */
void phrase::changePhraseContour(CONTOUR_TYPE contour, uint rate, globalsT glob) {
  uint tmpRate;
  int step = ((int)rate - 100)/(int)syllableVec.size();
  tmpRate=0;

  if (contour==rise || contour==fall) {
    for (uint tmpSyl=0; tmpSyl <syllableVec.size(); tmpSyl++) { 
      tmpRate = 100 + (step * tmpSyl);
      // cout << tmpSyl << " " << step<<" "<<tmpRate << " " << rate<<"\n";
      for (uint pho=0; pho<syllableVec[tmpSyl].PhonNum(); pho++) 
	syllableVec[tmpSyl].PhonVec()[pho].changeMeanF0(tmpRate);    
    }
  } else if (contour == straight) {
    // error("feature not implemented\n", -3);
    for (uint tmpSyl=0; tmpSyl <syllableVec.size(); tmpSyl++) { 
      int f0MeanDiff = (int) ((double) meanF0 / (double) syllableVec[tmpSyl].MeanF0() * 100.0);
      
      // cout <<f0MeanDiff <<"\n";
      for (uint pho=0; pho<syllableVec[tmpSyl].PhonNum(); pho++) {
	syllableVec[tmpSyl].PhonVec()[pho].changeMeanF0(f0MeanDiff);
	;
      }    
    }

  }
  if (glob.verbose)
    std::cerr << "changed f0-countour of phrase at rate "<<rate<<" \n"; 
  calcMeanF0();
}

/* *******************************************************************
   void changePhraseContourToAccent(uint rate, globalsT glob)
   args: uint rate
   returns: none
   effect: like changePhraseContour(), but repeated for every accented syllable
   *******************************************************************
   */
void phrase::changePhraseContourToAccent(uint rate, globalsT glob) {
  uint sylC=0, tmpRate;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    if (syllableVec[syl].Accent()==sentence) { // if the syl has accent
      int step = ((int)rate - 100)/(int)sylC;
      tmpRate=0;
      for (uint tmpSyl=syl-sylC; tmpSyl <= syl; tmpSyl++) { // foreach syl before the accent	
	tmpRate = 100 + (step *  (tmpSyl-(syl-sylC)));
	//	cout << tmpSyl << " " << step<<" "<<tmpRate << " " << rate<<"\n";
	syllableVec[tmpSyl].changeMeanF0(tmpRate);
	
      }
      sylC=0;
    } else
      sylC++;
  }
  if (glob.verbose)
    std::cerr << "changed f0-countour to accented syllables at rate "<<rate<<" \n"; 
  calcMeanF0();
}

/* *******************************************************************
   void addWave(uint accRate, uint nonAccRate, uint method, globalsT glob)
   args: uint accRate, uint nonAccRate, uint method
   returns: none
   effect: whole intonationContour is changed: the phrase-accented
   syllables get displaced according to <accRate>, the syllable between
   phrase-accents  get displaced according to <nonAccRate> and the other
   syllables get displaced by interpolation
   *******************************************************************
   */
void phrase::addWave(uint accRate, uint nonAccRate, uint method, globalsT glob) {
  std::vector<uint> tmpF0Vec, indexList, targetList;
  phon *pP;
  uint frameCounter=0;
  

  if (method==LINEAR) {
    indexList.push_back(0);
    targetList.push_back(syllableVec[0].MeanF0());
    // read in target vals and indices
    for (uint syl=0; syl<syllableVec.size(); syl++) {
      for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	// cout << (*pP).Name()<<" "<<indexList.size()<<"\n";
	pP = &syllableVec[syl].PhonVec()[pho];
	if (syllableVec[syl].Accent()==sentence && (*pP).Type()==vowel) {
	  if (indexList.size()>1) {
	    uint actIndex = frameCounter+(*pP).FrameNum()/2;
	    uint lastIndex = indexList[indexList.size()-1];
	    indexList.push_back(lastIndex+((actIndex-lastIndex)/2));
	    targetList.push_back(meanF0*nonAccRate/100);	  	    
	  }
	  indexList.push_back(frameCounter+(*pP).FrameNum()/2);
	  targetList.push_back(syllableVec[syl].MeanF0()*accRate/100);	  
	}
	for (uint i=0; i<(*pP).FrameNum(); i++)
	  tmpF0Vec.push_back((*pP).F0Vec()[i]);
	frameCounter += (*pP).FrameNum();
      }
    }
    indexList.push_back(frameCounter);
    targetList.push_back(syllableVec[syllableVec.size()-1].MeanF0());

    // for (uint i=0; i<indexList.size(); i++)
    //  cout <<indexList[i]<<" "<< targetList[i] <<"\n";

    // modify F0Vals    
    for (uint i=0; i<indexList.size()-1; i++) {
      uint startIndex=indexList[i];
      uint endIndex=indexList[i+1];
      uint startVal=targetList[i];
      uint endVal=targetList[i+1];

      // count voiced Frames
      uint vocCounter = 0;
      for (uint k=startIndex; k<endIndex; k++)
	if (tmpF0Vec[k] != 0)
	  vocCounter++;  
      if (startVal<endVal) {
	double step = (int) (endVal-startVal) / (double) vocCounter;
	// cout <<vocCounter<<" "<<step<<" "<<startVal<<" "<<endVal<<"\n";
	vocCounter = 0;
	for (uint k=startIndex; k<endIndex; k++) {
	  if (tmpF0Vec[k] != 0) {
	    tmpF0Vec[k] = startVal+(uint) (vocCounter*step);
	    vocCounter++;
	  }
	}
      } else if  (startVal > endVal) {
	double step = (int) (startVal-endVal) / (double) vocCounter;
	// cout <<vocCounter<<" "<<step<<" "<<startVal<<" "<<endVal<<"\n";
	vocCounter = 0;
	for (uint k=startIndex; k<endIndex; k++) {
	  if (tmpF0Vec[k] != 0) {
	    tmpF0Vec[k] = startVal-(uint) (vocCounter*step);
	    vocCounter++;
	  }
	}
      }
      
    }
    // assign new f0 vals to phones
    frameCounter = 0;
    for (uint syl=0; syl<syllableVec.size(); syl++) {
      for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	pP = &syllableVec[syl].PhonVec()[pho];
	std::vector<uint> tmpValVec(0);
	for (uint i=0; i<(*pP).FrameNum(); i++) {
	  tmpValVec.push_back(tmpF0Vec[frameCounter]);
	  frameCounter++;
	}
	(*pP).setF0Vec(tmpValVec, glob);
      }
    }
    //cout <<indexList.size()<<"\n";
  } else if (method==SYLLABLE_BASED) {
    indexList.push_back(0);
    targetList.push_back(100);
    
    for (uint syl=0; syl<syllableVec.size(); syl++) {
	if (syllableVec[syl].Accent()==sentence) {
	  if (indexList.size()>1) {
	    uint actIndex = syl;
	    uint lastIndex = indexList[indexList.size()-1];
	    indexList.push_back(lastIndex+((actIndex-lastIndex)/2));
	    targetList.push_back(nonAccRate);  	    
	  }
	  indexList.push_back(syl);
	  targetList.push_back(accRate);	  	  
	}      
    }
    indexList.push_back(syllableVec.size());
    targetList.push_back(100);

    for (uint i=0; i<indexList.size()-1; i++) {      
      uint startIndex=indexList[i];
      uint endIndex=indexList[i+1];
      uint startVal=targetList[i];
      uint endVal=targetList[i+1];

      // cout << startIndex<<" "<<startVal<<" "<<endIndex<<" "<<endVal<<"\n";

      if (startVal<endVal) {
	double step = (double) (endVal-startVal) / (double) (endIndex-startIndex);
	for (uint syl=startIndex; syl<endIndex; syl++) {
	  startVal += (uint) step;
	  // cout << startVal<<" "<<step<<"\n";
	  syllableVec[syl].changeMeanF0(startVal);
	}      
      } else if (startVal>endVal) {
	double step = (double) (startVal-endVal) / (double) (endIndex-startIndex);
	for (uint syl=startIndex; syl<endIndex; syl++) {
	  startVal -= (uint) step;
	  // cout << startVal<<" "<<step<<"\n";
	  syllableVec[syl].changeMeanF0(startVal);
	}      
      } 
    }
    
  } else
    error("phrase::addWave: method not implemented\n", -3);
  if (glob.verbose)
    std::cerr << "changed f0-countour to wave model at accRate "<<accRate<<" and nonAccRate "<<nonAccRate<<"\n";   
  calcMeanF0();
}

// articulatory modifications: 

/* *******************************************************************
     void overshootVowels(ACCENT_TYPE accent, uint rate, globalsT glob)
     args: ACCENT_TYPE accent, uint rate
     returns: none
     effect:  all formantVals in f1 and f2 of vowels in syllables with <accent>
     get displaced away from the center freqencies by adding the 
     percentage by <rate> and distance to center frequency.
     *******************************************************************
     */ 
void phrase::overshootVowels(ACCENT_TYPE accent, uint rate, globalsT glob) {
  phon *pP;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    if (syllableVec[syl].Accent()==accent) {
      for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	pP = &syllableVec[syl].PhonVec()[pho];
	if ((*pP).Type()==vowel) { // && ! (*pP).Diphtong()) {
	  PHON_FEATURES tmpPhonFeatures= (*pP).PhonFeatures();
	  tmpPhonFeatures.overshoot = true;
	  tmpPhonFeatures.overshootRate = rate;
	  (*pP).setPhonFeatures(tmpPhonFeatures);
	}
      }
    }
  }
  if (glob.verbose)
    std::cerr << "added overshoot at "<<rate<<" for accent-type: "<<(uint)accent<<"\n";
}
void phrase::undershootVowels(ACCENT_TYPE accent, uint rate, globalsT glob) {
  phon *pP;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    if (syllableVec[syl].Accent()==accent) {
      for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	pP = &syllableVec[syl].PhonVec()[pho];
	if ((*pP).Type() == vowel) {
	  PHON_FEATURES tmpPhonFeatures= (*pP).PhonFeatures();
	  tmpPhonFeatures.undershoot = true;
	  tmpPhonFeatures.undershootRate = rate;	  
	  (*pP).setPhonFeatures(tmpPhonFeatures);
	}
      }
    }
  }	
  if (glob.verbose)
    std::cerr <<"added undershoot at rate: "<<rate<<" for accent-type: "<<(uint)accent<<"\n";
}
void phrase::spread(uint rate, globalsT glob) {
  phon *pP;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      pP = &syllableVec[syl].PhonVec()[pho];
      if ((*pP).Type()==vowel) {
	PHON_FEATURES tmpPhonFeatures= (*pP).PhonFeatures();
	tmpPhonFeatures.spread = true;
	tmpPhonFeatures.spreadRate = rate;	  
	(*pP).setPhonFeatures(tmpPhonFeatures);
      }
    }
  }	
  if (glob.verbose)
    std::cerr <<"added lip-spreading at rate: "<<rate<<"\n";
}

void phrase::rounded(uint rate, globalsT glob) {
  phon *pP;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      pP = &syllableVec[syl].PhonVec()[pho];
      if ((*pP).Type() == vowel) {
	PHON_FEATURES tmpPhonFeatures= (*pP).PhonFeatures();
	tmpPhonFeatures.rounded = true;
	tmpPhonFeatures.roundedRate = rate;	  
	(*pP).setPhonFeatures(tmpPhonFeatures);
      }
    }
  }	
  if (glob.verbose)
    std::cerr <<"added lip-rounding at rate: "<<rate<<"\n";
}
void phrase::headSize(uint rate, globalsT glob) {
  phon *pP;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      pP = &syllableVec[syl].PhonVec()[pho];
      if ((*pP).Voiced()) {
	PHON_FEATURES tmpPhonFeatures= (*pP).PhonFeatures();
	tmpPhonFeatures.headSize = true;
	tmpPhonFeatures.headSizeRate = rate;	  
	(*pP).setPhonFeatures(tmpPhonFeatures);
      }
    }
  }	
  if (glob.verbose)
    std::cerr <<"changed head-size at rate: "<<rate<<"\n";
}

/* *******************************************************************
   void coarticulation(uint rate, CO_TYPE coType, globalsT glob)
   args: uint rate, CO_TYPE coType
   returns: none
   effect: each phone gets features added at the borders from the 
   neighboring phones, depending on <coType:regressiv, progrssive, both>
   *******************************************************************
   */
void phrase::coarticulation(uint rate, CO_TYPE coType, globalsT glob) {
  phon *pP;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      pP = &syllableVec[syl].PhonVec()[pho];
      PHON_FEATURES tmpPhonFeatures= (*pP).PhonFeatures();
      tmpPhonFeatures.coarticulation = true;
      tmpPhonFeatures.coarticulationRate = rate;
      tmpPhonFeatures.coarticulationType = coType;      
      (*pP).setPhonFeatures(tmpPhonFeatures);
    }
  }	
  if(glob.verbose)
    std::cerr << "added coarticulation with rate: "<<rate<<"\n";
}
/* ****************************************************************
   void phrase::assimilateConsonants(globalsT glob)
   args: globals
   returns: none
   effect: add voicing to unvoicec fricatives in VCV-environment
   ****************************************************************
*/
void phrase::assimilateConsonants(globalsT glob) {
  PHON_TYPE prevT, nextT;
  phon *pP;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      pP = &syllableVec[syl].PhonVec()[pho];
      if (pho==syllableVec[syl].PhonNum()-1)
	nextT = syllableVec[syl+1].PhonVec()[0].Type();
      else
	nextT = syllableVec[syl].PhonVec()[pho+1].Type();
      
      if (!(syl==0&&pho==0) && !(syl==syllableVec.size()-1 && 
				 pho==syllableVec[syl].PhonNum()-1))
	if ((*pP).Manner() == fricative_voiceless && prevT==vowel && nextT==vowel) {
	  PHON_FEATURES tmpPhonFeatures= (*pP).PhonFeatures();
	  tmpPhonFeatures.voiced = true;
	  tmpPhonFeatures.vocStart = 0;
	  tmpPhonFeatures.vocStop = (*pP).FrameNum();	  
	  (*pP).setPhonFeatures(tmpPhonFeatures);
	}
      prevT = (*pP).Type();
    }
  }
  if(glob.verbose)
    std::cerr << "assimilated consonants in VCV-environment\n";
}

/* *******************************************************************
   void addJitter(ACCENT_TYPE accent, uint rate, uint method, globalsT glob)
   args: ACCENT_TYPE accent, uint rate, uint method
   returns: none
   effect: simulates Jitter at all voiced phones in syllables with <accent>.
   If <method> = 1, all nonzero f0Vals get displaced about <rate> 
   alternating down and up. (0 > rate < 10)
   If <method> = 2, the klattSyn parameter skew is set to <rate> (0 > rate < 300)
   *******************************************************************
   */

void phrase::addJitter(ACCENT_TYPE accent, uint rate, uint method, globalsT glob) {
  phon *pP;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    if (syllableVec[syl].Accent()==accent) {
      for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
	pP = &syllableVec[syl].PhonVec()[pho];
	if ((*pP).Type() == vowel) {
	  PHON_FEATURES tmpPhonFeatures= (*pP).PhonFeatures();
	  tmpPhonFeatures.jitter = true;
	  tmpPhonFeatures.jitterRate = rate;
	  tmpPhonFeatures.jitterMethod = method;	  
	  (*pP).setPhonFeatures(tmpPhonFeatures);
	}
      }
    }
  }
  if(glob.verbose)
    std::cerr << "added jitter with rate: "<<rate<<"\n";
}
/* *******************************************************************
   void addBreathy(uint rate, globalsT glob)
   args: uint rate
   returns: none
   effect: simulates breathy phonation at all vowels
   *******************************************************************
   */
void phrase::addBreathy(uint rate, globalsT glob) {
  phon *pP;
  if (rate > 100)
    error("phrase::addBreathy: rate>100\n",-5);
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      pP = &syllableVec[syl].PhonVec()[pho];
      // if ((*pP).Voiced() && (*pP).Manner()!=stop_voiced && (*pP).Name()!="h") {
      if ((*pP).Type() == vowel || (*pP).Manner() == nasal) {
	PHON_FEATURES tmpPhonFeatures= (*pP).PhonFeatures();
	tmpPhonFeatures.breathy = true;
	tmpPhonFeatures.brtStart = 0;
	tmpPhonFeatures.brtStop = (*pP).FrameNum();	  
	tmpPhonFeatures.brtRate = rate;
	(*pP).setPhonFeatures(tmpPhonFeatures);
      }
    }
  }
  if(glob.verbose)
    std::cerr << "added breathy voice with rate: "<<rate<<"\n";
}
  /* *******************************************************************
     void addTense(uint rate, globalsT glob)
     args: uint rate
     returns: none
     effect: simulates tense phonation at all vowels
     *******************************************************************
  */
void phrase::addTense(uint rate, globalsT glob) {
  phon *pP;
  if (rate > 100)
    error("phrase::addWhisper: rate>100\n",-5);
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      pP = &syllableVec[syl].PhonVec()[pho];
      if ((*pP).Type()==vowel) {
	PHON_FEATURES tmpPhonFeatures= (*pP).PhonFeatures();
	tmpPhonFeatures.tense = true;
	tmpPhonFeatures.tenseRate = rate;
	(*pP).setPhonFeatures(tmpPhonFeatures);
      }
    }
  }
  if (glob.verbose)
    std::cerr << "added tensed voice at rate "<<rate<<" \n"; 
}
/* *******************************************************************
   void addWhisper(uint rate, globalsT glob)
   args: uint rate
   returns: none
   effect: simulates whispery phonation at all vowels
   *******************************************************************
   */
void phrase::addWhisper(uint rate, globalsT glob) {
  phon *pP;
  if (rate > 100)
    error("phrase::addWhisper: rate>100\n",-5);
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      pP = &syllableVec[syl].PhonVec()[pho];
      if ((*pP).Voiced()) {
	PHON_FEATURES tmpPhonFeatures= (*pP).PhonFeatures();
	tmpPhonFeatures.whisper = true;
	tmpPhonFeatures.whisperRate = rate;
	(*pP).setPhonFeatures(tmpPhonFeatures);
      }
    }
  }
  if (glob.verbose)
    std::cerr << "added whispery voice at rate "<<rate<<" \n"; 
}
  /* *******************************************************************
     void addLaryngealized(uint rate, globalsT glob)
     args: uint rate
     returns: none
     effect: simulates laryngealized phonation at the beginning of vowels 
     after nonvoiced sounds
     *******************************************************************
  */
void phrase::addLaryngealized(uint rate, globalsT glob) {
  phon *pP;
  bool ok;
  if (rate > 100)
    error("phrase::addLaryngealized: rate>100\n",-5);
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      pP = &syllableVec[syl].PhonVec()[pho];
      if ((*pP).Type()==vowel && ok) {
	PHON_FEATURES tmpPhonFeatures= (*pP).PhonFeatures();
	tmpPhonFeatures.creaky = true;
	tmpPhonFeatures.creakyStart = 0;
	tmpPhonFeatures.creakyStop = (*pP).FrameNum()/2;	  
	tmpPhonFeatures.creakyRate = rate;
	(*pP).setPhonFeatures(tmpPhonFeatures);
      }
      if (!(*pP).Voiced())
	ok = true;
      else
	ok = false;
    }
  }
  if (glob.verbose)
    std::cerr << "added laryngealized voice at rate "<<rate<<" \n"; 
  calcMeanF0();
}
  /* *******************************************************************
     void addCreaky(uint rate, globalsT glob)
     args: uint rate
     returns: none
     effect: simulates creaky phonation at all vowels
     *******************************************************************
  */
void phrase::addCreaky(uint rate, globalsT glob) {
  phon *pP;
  if (rate > 100)
    error("phrase::addCreaky: rate>100\n",-5);
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      pP = &syllableVec[syl].PhonVec()[pho];
      if ((*pP).Voiced()) {
	PHON_FEATURES tmpPhonFeatures= (*pP).PhonFeatures();
	tmpPhonFeatures.creaky = true;
	tmpPhonFeatures.creakyStart = 0;
	tmpPhonFeatures.creakyStop = (*pP).FrameNum();	  
	tmpPhonFeatures.creakyRate = rate;
	(*pP).setPhonFeatures(tmpPhonFeatures);
      }
    }
  }
  calcMeanF0();
  if (glob.verbose)
    std::cerr << "added creaky voice at rate "<<rate<<" \n"; 
}
  /* *******************************************************************
     void addFalsett(uint rate, globalsT glob)
     args: uint rate
     returns: none
     effect: simulates falsett phonation at all vowels
     *******************************************************************
  */

void phrase::addFalsett(uint rate, globalsT glob) {
  phon *pP;
  if (rate > 100)
    error("phrase::addFalsett: rate>100\n",-5);
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      pP = &syllableVec[syl].PhonVec()[pho];
      if ((*pP).Voiced()) {
	PHON_FEATURES tmpPhonFeatures= (*pP).PhonFeatures();
	tmpPhonFeatures.falsett = true;
	tmpPhonFeatures.falsettRate = rate;
	(*pP).setPhonFeatures(tmpPhonFeatures);
      }
    }
  }
  calcMeanF0();
  if (glob.verbose)
    std::cerr << "added falsett voice at rate "<<rate<<" \n"; 
}
void phrase::printSenSynFile(globalsT glob, std::ostream &outFile) {
  uint start=0;
  outFile <<  "parameter file for the klatt-formant speech-synthesizer\n implementation: sensyn, sensimetrics coorp. \n";
  outFile <<  "generated by emoSyn\n - speechsynthesizer-frontend for emotional speech,\n author felixbur@globw.tu-berlin.de\n";
  outFile <<  "6\n7\n8\n9\n";
  outFile <<  "60 parameters\n";
  outFile <<  "11\n12\n13\n";

  outFile <<  "DU   C   30   "<<dur<<"  5000 Duration of the utterance, in msec\n";
  outFile <<  "UI   C    1     "<<glob.ui<<"    20  Update interval for parameter reset, in msec\n";
  outFile <<  "SR   C 5000 "<<glob.sr<<" 20000  Output sampling rate, in samples/sec\n";
  outFile <<  "NF   C    1     "<<glob.nf<<"     6  Number of formants in cascade branch\n";
  outFile <<  "SS   C    1     "<<glob.ss<<"     3  Source switch (1=impulse, 2=natural, 3=LF model)\n";
  outFile <<  "RS   C    1     "<<glob.rs<<"  8191  Random seed (initial value of random # generator)\n";
  outFile <<  "SB   C    0     "<<glob.sb<<"     1  Same noise burst, reset RS if AF=AH=0, 0=no,1=yes\n";
  outFile <<  "CP   C    0     "<<glob.cp<<"     1  0=Cascade, 1=Parallel tract excitation by AV\n";
  outFile <<  "OS   C    0     "<<glob.os<<"    20  Output selector (0=normal,1=voicing source,...)\n";
  outFile <<  "GV   C    0    "<<glob.gv<<"    80  Overall gain scale factor for AV, in dB\n";
  outFile <<  "GH   C    0    "<<glob.gh<<"    80  Overall gain scale factor for AH, in dB\n";
  outFile <<  "GF   C    0    "<<glob.gf<<"    80  Overall gain scale factor for AF, in dB\n";
  if (glob.f0Dyn) 
    outFile <<  "F0   V    0  "<<glob.f0<<"  5000  Fundamental frequency, in tenths of a Hz\n";
  else
    outFile <<  "F0   v    0  "<<glob.f0<<"  5000  Fundamental frequency, in tenths of a Hz\n";
  if (glob.avDyn)
    outFile <<  "AV   V    0    "<<glob.av<<"    80  Amplitude of voicing, in dB\n";
  else
    outFile <<  "AV   v    0    "<<glob.av<<"    80  Amplitude of voicing, in dB\n"; 
  if (glob.oqDyn)
    outFile <<  "OQ   V   10    "<<glob.oq<<"    99  Open quotient (voicing open-time/period), in %\n";
  else
    outFile <<  "OQ   v   10    "<<glob.oq<<"    99  Open quotient (voicing open-time/period), in %\n";
  if (glob.sqDyn)
    outFile <<  "SQ   V  100   "<<glob.sq<<"   500  Speed quotient (rise/fall time, LF model), in %\n";
  else
    outFile <<  "SQ   v  100   "<<glob.sq<<"   500  Speed quotient (rise/fall time, LF model), in %\n";
  if (glob.tlDyn)
    outFile <<  "TL   V    0     "<<glob.tl<<"    41  Extra tilt of voicing spectrum, dB down @ 3 kHz\n";
  else
    outFile <<  "TL   v    0     "<<glob.tl<<"    41  Extra tilt of voicing spectrum, dB down @ 3 kHz\n";
  if (glob.flDyn)
    outFile <<  "FL   V    0     "<<glob.fl<<"   100  Flutter (random fluct in f0), in % of maximum\n";
  else
    outFile <<  "FL   v    0     "<<glob.fl<<"   100  Flutter (random fluct in f0), in % of maximum\n";  
  if (glob.diDyn) 
    outFile <<  "DI   V    0     "<<glob.di<<"   100  Diplophonia (alt periods closer), in % of max\n";
  else
    outFile <<  "DI   v    0     "<<glob.di<<"   100  Diplophonia (alt periods closer), in % of max\n";
  if (glob.ahDyn)
    outFile <<  "AH   V    0     "<<glob.ah<<"    80  Amplitude of aspiration, in dB\n";
  else
    outFile <<  "AH   v    0     "<<glob.ah<<"    80  Amplitude of aspiration, in dB\n";
  if (glob.afDyn)
    outFile <<  "AF   V    0     "<<glob.af<<"    80  Amplitude of frication, in dB\n";
  else
    outFile <<  "AF   v    0     "<<glob.af<<"    80  Amplitude of frication, in dB\n";
  if (glob.f1Dyn)
    outFile <<  "F1   V  180   "<<glob.f1<<"  1300  Frequency of 1st formant, in Hz\n";
  else
    outFile <<  "F1   v  180   "<<glob.f1<<"  1300  Frequency of 1st formant, in Hz\n";
  if (glob.b1Dyn) 
    outFile <<  "B1   V   30    "<<glob.b1<<"  1000  Bandwidth of 1st formant, in Hz\n";
  else
    outFile <<  "B1   v   30    "<<glob.b1<<"  1000  Bandwidth of 1st formant, in Hz\n";
  if (glob.df1Dyn)
    outFile <<  "DF1  V    0     "<<glob.df1<<"   100  Change in F1 during open portion of period, in Hz\n";
  else
    outFile <<  "DF1  v    0     "<<glob.df1<<"   100  Change in F1 during open portion of period, in Hz\n";
  if (glob.db1Dyn)
    outFile <<  "DB1  V    0     "<<glob.db1<<"   400  Change in B1 during open portion of period, in Hz\n";
  else
    outFile <<  "DB1  v    0     "<<glob.db1<<"   400  Change in B1 during open portion of period, in Hz\n";
  if (glob.f2Dyn)
    outFile <<  "F2   V  550  "<<glob.f2<<"  3000  Frequency of 2nd formant, in Hz\n";
  else
    outFile <<  "F2   v  550  "<<glob.f2<<"  3000  Frequency of 2nd formant, in Hz\n";
  if (glob.b2Dyn)
    outFile <<  "B2   V   40   "<<glob.b2<<"  90   Bandwidth of 2nd formant, in Hz\n";
  else
    outFile <<  "B2   v   40  "<<glob.b2<<"  90    Bandwidth of 2nd formant, in Hz\n";
  if (glob.f3Dyn)
    outFile <<  "F3   V 1200 "<<glob.f3<<" 2500    Frequency of 3rd formant, in Hz\n";
  else 
    outFile <<  "F3   v 1200 "<<glob.f3<<"  2500   Frequency of 3rd formant, in Hz\n";
  if (glob.b3Dyn)
    outFile <<  "B3   V   60  "<<glob.b3<<"   150  Bandwidth of 3rd formant, in Hz\n";
  else
    outFile <<  "B3   v   60 "<<glob.b3<<"   150   Bandwidth of 3rd formant, in Hz\n";
  if (glob.f4Dyn)    
    outFile <<  "F4   V 2400  "<<glob.f4<<"  4990  Frequency of 4th formant, in Hz\n";
  else
    outFile <<  "F4   v 2400  "<<glob.f4<<"  4990  Frequency of 4th formant, in Hz\n";
  if (glob.b4Dyn)
    outFile <<  "B4   V  100   "<<glob.b4<<"  1000  Bandwidth of 4th formant, in Hz\n";
  else
    outFile <<  "B4   v  100   "<<glob.b4<<"  1000  Bandwidth of 4th formant, in Hz\n";
  if (glob.f5Dyn)
    outFile <<  "F5   V 3000  "<<glob.f5<<"  4990  Frequency of 5th formant, in Hz\n";
  else
    outFile <<  "F5   v 3000  "<<glob.f5<<"  4990  Frequency of 5th formant, in Hz\n";
  if (glob.b5Dyn)
    outFile <<  "B5   V  100   "<<glob.b5<<"  1500  Bandwidth of 5th formant, in Hz\n";
  else
    outFile <<  "B5   v  100   "<<glob.b5<<"  1500  Bandwidth of 5th formant, in Hz\n";
  if (glob.f6Dyn)
    outFile <<  "F6   V 3000  "<<glob.f6<<"  4990  Frequency of 6th formant, in Hz (applies if NF=6)\n";
  else
    outFile <<  "F6   v 3000  "<<glob.f6<<"  4990  Frequency of 6th formant, in Hz (applies if NF=6)\n";
  if (glob.b6Dyn)
    outFile <<  "B6   V  100   "<<glob.b6<<"  4000  Bandwidth of 6th formant, in Hz (applies if NF=6)\n";
  else
    outFile <<  "B6   v  100   "<<glob.b6<<"  4000  Bandwidth of 6th formant, in Hz (applies if NF=6)\n";
  if (glob.fnpDyn)
    outFile <<  "FNP  V  180   "<<glob.fnp<<"  2000  Frequency of nasal pole, in Hz\n";
  else
    outFile <<  "FNP  v  180   "<<glob.fnp<<"  2000  Frequency of nasal pole, in Hz\n";
  if (glob.bnpDyn)
    outFile <<  "BNP  V   40    "<<glob.bnp<<"  1000  Bandwidth of nasal pole, in Hz\n";
  else
    outFile <<  "BNP  v   40    "<<glob.bnp<<"  1000  Bandwidth of nasal pole, in Hz\n";
  if (glob.fnzDyn)
    outFile <<  "FNZ  V  180   "<<glob.fnz<<"  2000  Frequency of nasal zero, in Hz\n";
  else
    outFile <<  "FNZ  v  180   "<<glob.fnz<<"  2000  Frequency of nasal zero, in Hz\n";
  if (glob.bnzDyn)
    outFile <<  "BNZ  V   40    "<<glob.bnz<<"  1000  Bandwidth of nasal zero, in Hz\n";
  else
    outFile <<  "BNZ  v   40    "<<glob.bnz<<"  1000  Bandwidth of nasal zero, in Hz\n";
  if (glob.ftpDyn)
    outFile <<  "FTP  V  300  "<<glob.ftp<<"  3000  Frequency of tracheal pole, in Hz\n";
  else
    outFile <<  "FTP  v  300  "<<glob.ftp<<"  3000  Frequency of tracheal pole, in Hz\n";
  if (glob.btpDyn)
    outFile <<  "BTP  V   40   "<<glob.btp<<"  1000  Bandwidth of tracheal pole, in Hz\n";
  else
    outFile <<  "BTP  v   40   "<<glob.btp<<"  1000  Bandwidth of tracheal pole, in Hz\n";
  if (glob.ftzDyn)
    outFile <<  "FTZ  V  300  "<<glob.ftz<<"  3000  Frequency of tracheal zero, in Hz\n";
  else
    outFile <<  "FTZ  v  300  "<<glob.ftz<<"  3000  Frequency of tracheal zero, in Hz\n";
  if (glob.btzDyn)
    outFile <<  "BTZ  V   40   "<<glob.btz<<"  2000  Bandwidth of tracheal zero, in Hz\n";
  else
    outFile <<  "BTZ  v   40   "<<glob.btz<<"  2000  Bandwidth of tracheal zero, in Hz\n";
  if (glob.a2fDyn)
    outFile <<  "A2F  V    0     "<<glob.a2f<<"    80  Amp of fric-excited parallel 2nd formant, in dB\n";
  else
    outFile <<  "A2F  v    0     "<<glob.a2f<<"    80  Amp of fric-excited parallel 2nd formant, in dB\n";
  if (glob.a3fDyn)
    outFile <<  "A3F  V    0     "<<glob.a3f<<"    80  Amp of fric-excited parallel 3rd formant, in dB\n";
  else
    outFile <<  "A3F  v    0     "<<glob.a3f<<"    80  Amp of fric-excited parallel 3rd formant, in dB\n";
  if (glob.a4fDyn)
    outFile <<  "A4F  V    0     "<<glob.a4f<<"    80  Amp of fric-excited parallel 4th formant, in dB\n";
  else
    outFile <<  "A4F  v    0     "<<glob.a4f<<"    80  Amp of fric-excited parallel 4th formant, in dB\n";
  if (glob.a5fDyn)
    outFile <<  "A5F  V    0     "<<glob.a5f<<"    80  Amp of fric-excited parallel 5th formant, in dB\n";
  else
    outFile <<  "A5F  v    0     "<<glob.a5f<<"    80  Amp of fric-excited parallel 5th formant, in dB\n";
  if (glob.a6fDyn)
    outFile <<  "A6F  V    0     "<<glob.a6f<<"    80  Amp of fric-excited parallel 6th formant, in dB\n";
  else
    outFile <<  "A6F  v    0     "<<glob.a6f<<"    80  Amp of fric-excited parallel 6th formant, in dB\n";
  if (glob.abDyn)
    outFile <<  "AB   V    0     "<<glob.ab<<"    80  Amp of fric-excited parallel bypass path, in dB\n";
  else
    outFile <<  "AB   v    0     "<<glob.ab<<"    80  Amp of fric-excited parallel bypass path, in dB\n";
  if (glob.b2pDyn)
    outFile <<  "B2F  V   40   "<<glob.b2p<<"  1000  Bw of fric-excited parallel 2nd formant, in Hz\n";
  else
    outFile <<  "B2F  v   40   "<<glob.b2p<<"  1000  Bw of fric-excited parallel 2nd formant, in Hz\n";
  if (glob.b3pDyn)
    outFile <<  "B3F  V   60   "<<glob.b3p<<"  1000  Bw of fric-excited parallel 3rd formant, in Hz\n";
  else
    outFile <<  "B3F  v   60   "<<glob.b3p<<"  1000  Bw of fric-excited parallel 3rd formant, in Hz\n";
  if (glob.b4pDyn)
    outFile <<  "B4F  V  100   "<<glob.b4p<<"  1000  Bw of fric-excited parallel 4th formant, in Hz\n";
  else
    outFile <<  "B4F  v  100   "<<glob.b4p<<"  1000  Bw of fric-excited parallel 4th formant, in Hz\n";
  if (glob.b5pDyn)
    outFile <<  "B5F  V  100   "<<glob.b5p<<"  1500  Bw of fric-excited parallel 5th formant, in Hz\n";
  else
    outFile <<  "B5F  v  100   "<<glob.b5p<<"  1500  Bw of fric-excited parallel 5th formant, in Hz\n";
  if (glob.b6pDyn)
    outFile <<  "B6F  V  100  "<<glob.b6p<<"  4000  Bw of fric-excited parallel 6th formant, in Hz\n";
  else
    outFile <<  "B6F  v  100  "<<glob.b6p<<"  4000  Bw of fric-excited parallel 6th formant, in Hz\n";
  if (glob.anvDyn)
    outFile <<  "ANV  V    0     "<<glob.anv<<"    80  Amp of voice-excited parallel nasal form., in dB\n";
  else
    outFile <<  "ANV  v    0     "<<glob.anv<<"    80  Amp of voice-excited parallel nasal form., in dB\n";
  if (glob.a1vDyn)
    outFile <<  "A1V  V    0    "<<glob.a1v<<"    80  Amp of voice-excited parallel 1st formant, in dB\n";
  else
    outFile <<  "A1V  v    0    "<<glob.a1v<<"    80  Amp of voice-excited parallel 1st formant, in dB\n";
  if (glob.a2vDyn)
    outFile <<  "A2V  V    0    "<<glob.a2v<<"    80  Amp of voice-excited parallel 2nd formant, in dB\n";
  else
    outFile <<  "A2V  v    0    "<<glob.a2v<<"    80  Amp of voice-excited parallel 2nd formant, in dB\n";
  if (glob.a3vDyn)
    outFile <<  "A3V  V    0    "<<glob.a3v<<"    80  Amp of voice-excited parallel 3rd formant, in dB\n";
  else
    outFile <<  "A3V  v    0    "<<glob.a3v<<"    80  Amp of voice-excited parallel 3rd formant, in dB\n";
  if (glob.a4vDyn)
    outFile <<  "A4V  V    0    "<<glob.a4v<<"    80  Amp of voice-excited parallel 4th formant, in dB\n";
  else
    outFile <<  "A4V  v    0    "<<glob.a4v<<"    80  Amp of voice-excited parallel 4th formant, in dB\n";
  if (glob.atvDyn)
    outFile <<  "ATV  V    0     "<<glob.atv<<"    80  Amp of voice-excited par tracheal formant, in dB\n";
  else
    outFile <<  "ATV  v    0     "<<glob.atv<<"    80  Amp of voice-excited par tracheal formant, in dB\n";
  
  outFile <<  "\n\n\n\n"; // skip four lines
  

  outFile <<  "Varied Parameters:\n";
  outFile.width(4);
  outFile <<  "time";
  if (glob.f0Dyn) outFile << "   F0";
  if (glob.avDyn) outFile << "   AV";
  if (glob.oqDyn) outFile << "   OQ";
  if (glob.sqDyn) outFile << "   SQ";
  if (glob.tlDyn) outFile << "   TL";
  if (glob.flDyn) outFile << "   FL";
  if (glob.diDyn) outFile << "   DI";
  if (glob.ahDyn) outFile << "   AH";
  if (glob.afDyn) outFile << "   AF";
  if (glob.f1Dyn) outFile << "   F1";
  if (glob.b1Dyn) outFile << "   B1";
  if (glob.df1Dyn) outFile << "   DF1";
  if (glob.db1Dyn) outFile << "   DB1";
  if (glob.f2Dyn) outFile << "   F2";
  if (glob.b2Dyn) outFile << "   B2";
  if (glob.f3Dyn) outFile << "   F3";
  if (glob.b3Dyn) outFile << "   B3";
  if (glob.f4Dyn) outFile << "   F4";
  if (glob.b4Dyn) outFile << "   B4";
  if (glob.f5Dyn) outFile << "   F5";
  if (glob.b5Dyn) outFile << "   B5";
  if (glob.f6Dyn) outFile << "   F6";
  if (glob.b6Dyn) outFile << "   B6";
  if (glob.fnpDyn) outFile << "   FNP";
  if (glob.bnpDyn) outFile << "   BNP";
  if (glob.fnzDyn) outFile << "   FNZ";
  if (glob.bnzDyn) outFile << "   BNZ";
  if (glob.ftpDyn) outFile << "   FTP";
  if (glob.btpDyn) outFile << "   BTZ";
  if (glob.ftzDyn) outFile << "   FTZ";
  if (glob.btzDyn) outFile << "   BTZ";
  if (glob.a2fDyn) outFile << "   A2F";
  if (glob.a3fDyn) outFile << "   A3F";
  if (glob.a4fDyn) outFile << "   A4F";
  if (glob.a5fDyn) outFile << "   A5F";
  if (glob.a6fDyn) outFile << "   A6F";
  if (glob.abDyn) outFile << "   AB";
  if (glob.b2pDyn) outFile << "   B2F";
  if (glob.b3pDyn) outFile << "   B3F";
  if (glob.b4pDyn) outFile << "   B4F";
  if (glob.b5pDyn) outFile << "   B5F";
  if (glob.b6pDyn) outFile << "   B6F";
  if (glob.anvDyn) outFile << "   ANV";
  if (glob.a1vDyn) outFile << "   A1V";
  if (glob.a2vDyn) outFile << "   A2V";
  if (glob.a3vDyn) outFile << "   A3V";
  if (glob.a4vDyn) outFile << "   A4V";
  if (glob.atvDyn) outFile << "   ATV";

  outFile <<  "\n";
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      outFile << "# name of phone: "<<syllableVec[syl].PhonVec()[pho].Name()<<"\n";
      outFile << "# meaning of params:\n";
      outFile << "# time";
      if (glob.f0Dyn) outFile << " F0";
      if (glob.avDyn) outFile << " AV";
      if (glob.oqDyn) outFile << " OQ";
      if (glob.sqDyn) outFile << " SQ";
      if (glob.tlDyn) outFile << " TL";
      if (glob.flDyn) outFile << " FL";
      if (glob.diDyn) outFile << " DI";
      if (glob.ahDyn) outFile << " AH";
      if (glob.afDyn) outFile << " AF";
      if (glob.f1Dyn) outFile << " F1";
      if (glob.b1Dyn) outFile << " B1";
      if (glob.df1Dyn) outFile << " DF1";
      if (glob.db1Dyn) outFile << " DB1";
      if (glob.f2Dyn) outFile << " F2";
      if (glob.b2Dyn) outFile << " B2";
      if (glob.f3Dyn) outFile << " F3";
      if (glob.b3Dyn) outFile << " B3";
      if (glob.f4Dyn) outFile << " F4";
      if (glob.b4Dyn) outFile << " B4";
      if (glob.f5Dyn) outFile << " F5";
      if (glob.b5Dyn) outFile << " B5";
      if (glob.f6Dyn) outFile << " F6";
      if (glob.b6Dyn) outFile << " B6";
      if (glob.fnpDyn) outFile << " FNP";
      if (glob.bnpDyn) outFile << " BNP";
      if (glob.fnzDyn) outFile << " FNZ";
      if (glob.bnzDyn) outFile << " BNZ";
      if (glob.ftpDyn) outFile << " FTP";
      if (glob.btpDyn) outFile << " BTZ";
      if (glob.ftzDyn) outFile << " FTZ";
      if (glob.btzDyn) outFile << " BTZ";
      if (glob.a2fDyn) outFile << " A2F";
      if (glob.a3fDyn) outFile << " A3F";
      if (glob.a4fDyn) outFile << " A4F";
      if (glob.a5fDyn) outFile << " A5F";
      if (glob.a6fDyn) outFile << " A6F";
      if (glob.abDyn) outFile << " AB";
      if (glob.b2pDyn) outFile << " B2F";
      if (glob.b3pDyn) outFile << " B3F";
      if (glob.b4pDyn) outFile << " B4F";
      if (glob.b5pDyn) outFile << " B5F";
      if (glob.b6pDyn) outFile << " B6F";
      if (glob.anvDyn) outFile << " ANV";
      if (glob.a1vDyn) outFile << " A1V";
      if (glob.a2vDyn) outFile << " A2V";
      if (glob.a3vDyn) outFile << " A3V";
      if (glob.a4vDyn) outFile << " A4V";
      if (glob.atvDyn) outFile << " ATV";
      outFile <<  "\n";
      syllableVec[syl].PhonVec()[pho].printSenSynFrames(start, outFile, glob);
      start +=  syllableVec[syl].PhonVec()[pho].FrameNum() * glob.ui;
    }
  }
}
void phrase::readPhonData(std::string diphonBase, globalsT &glob) {
  
  // variable declarations
  std::string actName, nextName, requiredDiphon;
  int actFrameNum, actBurstStart, actAspStart;

  phon *actPhonP, *nextPhonP;
  std::string diphonType;
  std::string buffer;        // tmp-buffer for line in diphon-file
  std::vector<std::string> bufferVec;
  PHON_MANNER actManner;
  uint lineCnt=0; // Cnt of lines in diphon-file
  std::vector<uint> diphonFrameNums(0); // list of frameNums foreach diphon

  uint phonBrdFrm; // border frame foreach phon
  uint phonFrameNum; // frameNum in database of phon
  uint allFrameCnt=0; // help Counter for assignment of params to phones 

  // vectors for markers in diphons
  std::vector<uint> t1(0), t2(0), border(0);
  // t1: first transition, t2: 2. transition
  // border between diphones
  
  std::vector<uint> tmpF0;
  std::vector<uint> tmpAmp;
  std::vector<uint> tmpF1, tmpF2, tmpF3, tmpF4, tmpF5;
 
  // borders for shortening of phones 
  int leftBorder, rightBorder;
  uint burstStart, aspStart;

  uint phon=0;
  std::string diphonName;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {

      actPhonP = &syllableVec[syl].PhonVec()[pho];
      if (pho==syllableVec[syl].PhonNum()-1)
	if (syl==syllableVec.size()-1)
	  break;
	else
	  nextPhonP = &syllableVec[syl+1].PhonVec()[0];
      else
	nextPhonP = &syllableVec[syl].PhonVec()[pho+1];

      actName = (*actPhonP).Name();
      actFrameNum = (*actPhonP).FrameNum();

      nextName = (*nextPhonP).Name();      
      requiredDiphon = actName + "-" + nextName;
      requiredDiphon = diphonBase + "/" + requiredDiphon + ".dip";
      std::ifstream inFile(requiredDiphon.c_str());
      if (inFile.good()) {
	lineCnt = 0;
	while  (getline(inFile, buffer)) {
	  if (buffer != "" && buffer.at(0) != '#') {
	    bufferVec = string2vec(buffer);
	    if (lineCnt==0) {
	      diphonName = bufferVec[1];
	    }
	    if (lineCnt==1) {
	      if (bufferVec[0]!="frameNumber") error("error in diphon-file:"+diphonName+"\n",-3);
	      diphonFrameNums.push_back(atoi(bufferVec[1].c_str()));
	    }
	    else if (lineCnt==2) {
	      if (bufferVec[0]!="t1") error("error in diphon-file:"+diphonName+"\n",-3);
	      t1.push_back(atoi(bufferVec[1].c_str()));
	    } else if (lineCnt==3) {
	      if (bufferVec[0]!="border") error("error in diphon-file:"+diphonName+"\n",-3);
	      border.push_back(atoi(bufferVec[1].c_str()));
	    }  else if (lineCnt==4) {
	      if (bufferVec[0]!="t2") error("error in diphon-file:"+diphonName+"\n",-3);
	      t2.push_back(atoi(bufferVec[1].c_str()));
	    }
	    else if (lineCnt>4) {
	      tmpF0.push_back(atoi(bufferVec[0].c_str()));
	      tmpAmp.push_back(atoi(bufferVec[1].c_str()));
	      tmpF1.push_back(atoi(bufferVec[2].c_str()));
	      tmpF2.push_back(atoi(bufferVec[3].c_str()));
	      tmpF3.push_back(atoi(bufferVec[4].c_str()));
	      if (glob.use4Freq || glob.use5Freq) {
		tmpF4.push_back(atoi(bufferVec[5].c_str()));
	      }
	      if (glob.use5Freq) {
		tmpF5.push_back(atoi(bufferVec[6].c_str()));
	      }
	    }
	    lineCnt++;
	  } // if (buffer != "") 
	} // while (getline(inFile, buffer)) 
	inFile.close();
      } else {
	error("can't open diphon-file: " + requiredDiphon + "\n", -1);
      } // if (inFile.good())      
      phon++;
    } // foreach pho
  } // foreach syl
  
  // assign parameters to phones
  phon=0;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      actPhonP = &syllableVec[syl].PhonVec()[pho];
      actName = (*actPhonP).Name();
      actFrameNum = (*actPhonP).FrameNum();
      
      actManner = (*actPhonP).Manner();
      
      if (!(syl==0 && pho==0) && !(syl==syllableVec.size()-1 && pho==syllableVec[syl].PhonNum()-1) ) {  
	if (actManner != stop_voiced && actManner != stop_voiceless) {
	  // first phon should always be silence
	  if (phon==0) error("you've found a bug!!!\n",-50); 
	  phonFrameNum = diphonFrameNums[phon-1] - border[phon-1] + border[phon];
	  phonBrdFrm = diphonFrameNums[phon-1]-border[phon-1];
	  (*actPhonP).setSteadyStart(t2[phon-1] - border[phon-1]);
	  (*actPhonP).setSteadyEnd(diphonFrameNums[phon-1] - border[phon-1] + t1[phon]);
	  
	} else { // phon is stop
	  phonFrameNum = diphonFrameNums[phon-1] - border[phon-1] + border[phon];
	  phonBrdFrm = diphonFrameNums[phon-1]-border[phon-1];
	  burstStart = diphonFrameNums[phon-1] - border[phon-1];
	  aspStart = diphonFrameNums[phon-1] - border[phon-1] + t1[phon];
	  // cout << actName<<" "<<phonFrameNum<<" "<<burstStart<<" "<<aspStart<<"\n";
	}
	
	// copy original params
	
	if (actManner != silence || glob.copysynthesis==true) {
	  std::vector<uint> actTmpAmp(0), actTmpF1(0), actTmpF2(0), 
	    actTmpF3(0), actTmpF4(0), 
	    actTmpF5(0);
	  
	  for (uint phonFrameCnt=0; phonFrameCnt < phonFrameNum; phonFrameCnt++) {
	    actTmpAmp.push_back(tmpAmp[allFrameCnt]);
	    actTmpF1.push_back(tmpF1[allFrameCnt]);
	    actTmpF2.push_back(tmpF2[allFrameCnt]);
	    actTmpF3.push_back(tmpF3[allFrameCnt]);
	    if (glob.use4Freq || glob.use5Freq)
	      actTmpF4.push_back(tmpF4[allFrameCnt]);
	    if (glob.use5Freq) 
	      actTmpF5.push_back(tmpF5[allFrameCnt]);

	    allFrameCnt++;
	  } // for (uint phonFrameCnt=0; phonFrameCnt<phonFrameNum; phonFrameCnt++)
	  // check diphonborders for big freq-jumps
	  if (phonBrdFrm!=0 && phonBrdFrm!=phonFrameNum) {
	    if ((uint)abs((int)(actTmpF1[phonBrdFrm-1]-actTmpF1[phonBrdFrm]))>jumpTolerance && ! glob.warningsOff)
	      std::cerr<<"WARNING: readPhonData: big freq jump ("<<abs((int)(actTmpF1[phonBrdFrm-1]-actTmpF1[phonBrdFrm]))<<") for f1 at phon "<<actName<<"\n";
	    if ((uint)abs((int)(actTmpF2[phonBrdFrm-1]-actTmpF2[phonBrdFrm]))>jumpTolerance && ! glob.warningsOff)
	      std::cerr<<"WARNING: readPhonData: big freq jump ("<<abs((int)(actTmpF2[phonBrdFrm-1]-actTmpF2[phonBrdFrm]))<<") for f2 at phon "<<actName<<"\n";
	    if ((uint)abs((int)(actTmpF3[phonBrdFrm-1]-actTmpF3[phonBrdFrm]))>jumpTolerance && ! glob.warningsOff)
	      std::cerr<<"WARNING: readPhonData: big freq jump ("<<abs((int)(actTmpF3[phonBrdFrm-1]-actTmpF3[phonBrdFrm]))<<") for f3 at phon "<<actName<<"\n";
	  }
	  
	  // fill param vectors
	  if (glob.changeDurMethod == STEADY_STATE_CUT || (actManner==stop_voiced || actManner==stop_voiceless)) {
	    if (actManner != stop_voiced && actManner != stop_voiceless) {
	      leftBorder = (*actPhonP).SteadyStart();
	      rightBorder = (*actPhonP).SteadyEnd(); 
	    } else { // act phon is stop
	      leftBorder = 0; 
	      rightBorder =  burstStart;
	    }
	    // cout << actName<<" "<<(*actPhonP).FrameNum()<<" "<<leftBorder<<" "<<rightBorder<<" "<<phonFrameNum<<"\n";
	    (*actPhonP).setAmpVec(change_valNum((*actPhonP).Name(), (*actPhonP).FrameNum(), leftBorder, rightBorder, actTmpAmp), glob);  
	    (*actPhonP).setF1Vec(change_valNum((*actPhonP).Name(), (*actPhonP).FrameNum(), leftBorder, rightBorder, actTmpF1), glob);
	    (*actPhonP).setF2Vec(change_valNum((*actPhonP).Name(), (*actPhonP).FrameNum(), leftBorder, rightBorder, actTmpF2), glob);
	    (*actPhonP).setF3Vec(change_valNum((*actPhonP).Name(), (*actPhonP).FrameNum(), leftBorder, rightBorder, actTmpF3), glob);
	    if (glob.use4Freq || glob.use5Freq) 
	      (*actPhonP).setF4Vec(change_valNum((*actPhonP).Name(), (*actPhonP).FrameNum(), leftBorder, rightBorder, actTmpF4), glob);
	    if (glob.use5Freq)
	      (*actPhonP).setF5Vec(change_valNum((*actPhonP).Name(), (*actPhonP).FrameNum(), leftBorder, rightBorder, actTmpF5), glob);
	  } else { //  changeDurMethod == TIME_ALIGNED
	    std::vector<uint> tmpTimeVec;
	    for (uint i=0; i<phonFrameNum; i++)
	      tmpTimeVec.push_back(i*(100/phonFrameNum));
 	    (*actPhonP).setAmpVec(modelTrack((*actPhonP).Name(), (*actPhonP).FrameNum(), actTmpAmp, tmpTimeVec), glob);  
	    (*actPhonP).setF1Vec(modelTrack((*actPhonP).Name(), (*actPhonP).FrameNum(), actTmpF1, tmpTimeVec), glob);
	    (*actPhonP).setF2Vec(modelTrack((*actPhonP).Name(), (*actPhonP).FrameNum(), actTmpF2, tmpTimeVec), glob);
	    (*actPhonP).setF3Vec(modelTrack((*actPhonP).Name(), (*actPhonP).FrameNum(), actTmpF3, tmpTimeVec), glob);
	    if (glob.use4Freq || glob.use5Freq) 
	      (*actPhonP).setF4Vec(modelTrack((*actPhonP).Name(), (*actPhonP).FrameNum(), actTmpF4, tmpTimeVec), glob);
	    if (glob.use5Freq)
	      (*actPhonP).setF5Vec(modelTrack((*actPhonP).Name(), (*actPhonP).FrameNum(), actTmpF5, tmpTimeVec), glob);

	  }
	  if (actManner == stop_voiced || actManner == stop_voiceless) { 
	    // cout <<actName<<": bS:"<<burstStart<<", aS:"<<aspStart<<"\n";
	    if (glob.copysynthesis) {
	      if (burstStart < (phonFrameNum-actFrameNum)) {
		actBurstStart = 0;
		actAspStart = aspStart - burstStart;
	      } else { 
		actBurstStart = burstStart - (phonFrameNum-actFrameNum);
		actAspStart = aspStart - (phonFrameNum-actFrameNum);
	      }
	    } else {
	      if (actFrameNum>=2) {
		actBurstStart = actFrameNum-2;
		actAspStart = actFrameNum-1;		
	      } else if (actFrameNum==1) {
		actBurstStart = 0;
		actAspStart = 1;		
	      } else {
		actBurstStart = 0;
		actAspStart = 0;		
	      }
	    }
	    (*actPhonP).setBurstStart(actBurstStart);
	    (*actPhonP).setAspStart(actAspStart);
	    // cout <<actName<<", bS:"<<actBurstStart<<", aS: "<<actAspStart<<", frameLength: "<<actFrameNum<<", dataBaseLength: "<<phonFrameNum<<"\n";
	    
	  }
	  
	} else {
	  // for silent parts interpolate the formant tracks to avoid freq-jumps
	  uint startF1=tmpF1[allFrameCnt-1]; uint endF1=tmpF1[allFrameCnt];
	  (*actPhonP).setF1Vec(interpolateLinear((*actPhonP).FrameNum(), startF1, endF1), glob);
	  uint startF2=tmpF2[allFrameCnt-1]; uint endF2=tmpF2[allFrameCnt];
	  (*actPhonP).setF2Vec(interpolateLinear((*actPhonP).FrameNum(), startF2, endF2), glob);
	  uint startF3=tmpF3[allFrameCnt-1]; uint endF3=tmpF3[allFrameCnt];
	  (*actPhonP).setF3Vec(interpolateLinear((*actPhonP).FrameNum(), startF3, endF3), glob);
	} // if (actManner != silence)
      }
      if (syl==syllableVec.size()-1 && pho==syllableVec[syl].PhonNum()-1) {
	// for silence at end continue formant-tracks to avoid freq-jumps
	// cout <<tmpF1[allFrameCnt-1]<<"\n";
	uint startF1=tmpF1[allFrameCnt-1]; 
	(*actPhonP).setF1Vec(interpolateLinear((*actPhonP).FrameNum(), startF1, startF1), glob);
	uint startF2=tmpF2[allFrameCnt-1]; 
	(*actPhonP).setF2Vec(interpolateLinear((*actPhonP).FrameNum(), startF2, startF2), glob);
	uint startF3=tmpF3[allFrameCnt-1];
	(*actPhonP).setF3Vec(interpolateLinear((*actPhonP).FrameNum(), startF3, startF3), glob);
      }
      phon++;
    } // foreach pho
  }  // foreach syl
}


void phrase::readF0FromDB(std::string diphonBase, globalsT &glob) {
  
  // variable declarations
  std::string actName, nextName, requiredDiphon;
  phon *actPhonP, *nextPhonP;
  std::string diphonType;
  std::string buffer;        // tmp-buffer for line in diphon-file
  std::vector<std::string> bufferVec;
  PHON_MANNER actManner;
  uint lineCnt=0; // Cnt of lines in diphon-file
  std::vector<uint> diphonFrameNums(0); // list of frameNums foreach diphon

  uint phonBrdFrm; // border frame foreach phon
  uint phonFrameNum; // frameNum in database of phon
  uint allFrameCnt=0; // help Cnt for assignment of params to phones 

  // vectors for markers in diphons
  std::vector<uint> t1(0), t2(0), border(0);
  // t1: first transition, t2: 2. transition
  // border between diphones
  
  std::vector<uint> tmpF0;

  uint phon=0;
  std::string diphonName;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {

      actPhonP = &syllableVec[syl].PhonVec()[pho];
      if (pho==syllableVec[syl].PhonNum()-1)
	if (syl==syllableVec.size()-1)
	  break;
	else
	  nextPhonP = &syllableVec[syl+1].PhonVec()[0];
      else
	nextPhonP = &syllableVec[syl].PhonVec()[pho+1];

      actName = (*actPhonP).Name();
      nextName = (*nextPhonP).Name();

      requiredDiphon = actName + "-" + nextName;
      
      requiredDiphon = diphonBase + "/" + requiredDiphon + ".dip";
      //    cout << requiredDiphon << "\n";
      std::ifstream inFile(requiredDiphon.c_str());
      if (inFile.good()) {
	lineCnt = 0;
	while  (getline(inFile, buffer)) {
	  if (buffer != "" && buffer.at(0) != '#') {
	    bufferVec = string2vec(buffer);
	    if (lineCnt==0) {
	      diphonName = bufferVec[1];
	    }
	    if (lineCnt==1) {
	      if (bufferVec[0]!="frameNumber") error("error in diphon-file:"+diphonName+"\n",-3);
	      diphonFrameNums.push_back(atoi(bufferVec[1].c_str()));
	    }
	    else if (lineCnt==2) {
	      if (bufferVec[0]!="t1") error("error in diphon-file:"+diphonName+"\n",-3);
	      t1.push_back(atoi(bufferVec[1].c_str()));
	    } else if (lineCnt==3) {
	      if (bufferVec[0]!="border") error("error in diphon-file:"+diphonName+"\n",-3);
	      border.push_back(atoi(bufferVec[1].c_str()));
	    }  else if (lineCnt==4) {
	      if (bufferVec[0]!="t2") error("error in diphon-file:"+diphonName+"\n",-3);
	      t2.push_back(atoi(bufferVec[1].c_str()));
	    }
	    else if (lineCnt>4) {
	      tmpF0.push_back(atoi(bufferVec[0].c_str()));
	    }
	    lineCnt++;
	  } // if (buffer != "") 
	} // while (getline(inFile, buffer)) 
	inFile.close();
      } else {
	error("can't open diphon-file: " + requiredDiphon + "\n", -1);
      } // if (inFile.good())      
      phon++;
    } // foreach pho
  } // foreach syl
  
  // assign parameters to phones
  phon=0;
  for (uint syl=0; syl<syllableVec.size(); syl++) {
    for (uint pho=0; pho<syllableVec[syl].PhonNum(); pho++) {
      actPhonP = &syllableVec[syl].PhonVec()[pho];
      actName = (*actPhonP).Name();
      actManner = (*actPhonP).Manner();
      
      if (!(syl==0 && pho==0) && !(syl==syllableVec.size()-1 && pho==syllableVec[syl].PhonNum()-1) ) {  
	//if (actManner == silence) { 
	  // phonFrameNums.push_back(0);
	//} else 
	  if (actManner != stop_voiced && actManner != stop_voiceless) {
	  // first phon should always be silence
	  if (phon==0) error("you've found a bug!!!\n",-50); 
	  // cout << actName <<" " << diphonFrameNums[phon-1]-border[phon-1]+border[phon] <<"\n";
	  phonFrameNum = diphonFrameNums[phon-1] - border[phon-1] + border[phon];
	  phonBrdFrm = diphonFrameNums[phon-1]-border[phon-1];
	  (*actPhonP).setSteadyStart(t2[phon-1] - border[phon-1]);
	  (*actPhonP).setSteadyEnd(diphonFrameNums[phon-1] - border[phon-1] + t1[phon]);
	  // cout << actName <<" "<<phonFrameNum<<"\n";
	} else { // phon is stop
	  //	 cout << actName <<" " << diphonFrameNums[phon-1]-border[phon-1]+border[phon]<<"\n";
	  phonFrameNum = diphonFrameNums[phon-1] - border[phon-1] + border[phon];
	  phonBrdFrm = diphonFrameNums[phon-1]-border[phon-1];
	}
	
	// copy original params
	  //        if (actManner != silence) {
	  
	  std::vector<uint> actTmpF0(0);
	  
	  for (uint phonFrameCnt=0; phonFrameCnt < phonFrameNum; phonFrameCnt++) {
	    actTmpF0.push_back(tmpF0[allFrameCnt]);
	    allFrameCnt++;
	  } // for (uint phonFrameCnt=0; phonFrameCnt<phonFrameNum; phonFrameCnt++)
	  
	  // check diphonborders for big freq-jumps
	  
	  // fill param vectors
	  (*actPhonP).setF0Vec(actTmpF0, glob);  
	  
	  //}
      }
      phon++;
    } // foreach pho
  }  // foreach syl
}


